android - 如何在接收短信时获取联系人姓名

标签 android sms broadcastreceiver

我有以下代码来接收短信,我正在尝试获取联系人姓名。

package com.example.smsTest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.SmsMessage;
import android.widget.Toast;

public class SmsReceiver extends BroadcastReceiver {
    private SQLiteAdapter mySQLiteAdapter;

    @Override
    public void onReceive(Context context, Intent intent) {
        mySQLiteAdapter = new SQLiteAdapter(context);
        mySQLiteAdapter.openToRead();

        Message message = null;

        Bundle extras = intent.getExtras();
        if (extras == null)
            return;

        Object[] pdus = (Object[]) extras.get("pdus");
        for (int i = 0; i < pdus.length; i++) {
            SmsMessage SMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
            String sender = SMessage.getOriginatingAddress();
            String body = SMessage.getMessageBody().toString();

            message = mySQLiteAdapter.createMessage(sender, body);

            // A custom Intent that will used as another Broadcast
            Intent in = new Intent("SmsMessage.intent.MAIN").putExtra(
                    "get_msg", sender + ":" + body);

            // To display a Toast whenever there is an SMS.
            Toast.makeText(context, body, Toast.LENGTH_LONG).show();

            Uri personUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.CONTENT_FILTER_URI, SMessage.getOriginatingAddress());  

            Cursor cur = context.getContentResolver().query(personUri, new String[] { PhoneLookup.DISPLAY_NAME }, null, null, null );  

            if( cur.moveToFirst() ) {  
                         int nameIndex = cur.getColumnIndex(PhoneLookup.DISPLAY_NAME);  

                         String PersonName = cur.getString(nameIndex); 

                         Toast.makeText(context, PersonName, Toast.LENGTH_LONG).show();
            }
            cur.close();

            // You can place your check conditions here(on the SMS or the
            // sender)
            // and then send another broadcast
            context.sendBroadcast(in);

            // This is used to abort the broadcast and can be used to silently
            // process incoming message and prevent it from further being
            // broadcasted. Avoid this, as this is not the way to program an
            // app.
            this.abortBroadcast();
        }
    }
}

这是我添加的导致我的应用程序崩溃的代码:

Uri personUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.CONTENT_FILTER_URI, SMessage.getOriginatingAddress());  

Cursor cur = context.getContentResolver().query(personUri, new String[] { PhoneLookup.DISPLAY_NAME }, null, null, null );  

if( cur.moveToFirst() ) {  
             int nameIndex = cur.getColumnIndex(PhoneLookup.DISPLAY_NAME);  

             String PersonName = cur.getString(nameIndex); 

             Toast.makeText(context, PersonName, Toast.LENGTH_LONG).show();
}
cur.close();

我刚刚修改了这个 link 的答案中的代码.

现在应用程序在收到短信时崩溃。

最佳答案

试试这段代码

在广播接收器中

 public class SMSReceiver  extends BroadcastReceiver{

 String str = "";    
 String no = "";
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub

     Bundle bundle = intent.getExtras();  
        SmsMessage[] msgs = null;
        if (bundle != null)
        {
            //---retrieve the SMS message received---
            Object[] pdus = (Object[]) bundle.get("pdus");
            msgs = new SmsMessage[pdus.length];            
            for (int i=0; i<msgs.length; i++){
                msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);                

                str += msgs[i].getMessageBody().toString();
                str += "\n";    
                no = msgs[i].getOriginatingAddress();

                //Resolving the contact name from the contacts.
                Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(no));
                Cursor c = context.getContentResolver().query(lookupUri, new String[]{ContactsContract.Data.DISPLAY_NAME},null,null,null);
                try {
                    c.moveToFirst();
                 String  displayName = c.getString(0);
                String ContactName = displayName;   
                Toast.makeText(context, ContactName, Toast.LENGTH_LONG).show();

                } catch (Exception e) {
                    // TODO: handle exception
                }finally{
                    c.close();
                }

            }
        }
    }
}

您必须使用 intentfilter 在 list 中注册此广播接收器

    <receiver android:name="SMSReceiver">

         <intent-filter> 
             <action android:name= "android.provider.Telephony.SMS_RECEIVED" />
         </intent-filter> 

    </receiver>

此外,您还必须添加用户权限,例如

<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>

关于android - 如何在接收短信时获取联系人姓名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16074617/

相关文章:

java.lang.NullPointerException : Attempt to invoke virtual method 'android.view.View android.app.Activity.findViewById(int)' on a null object reference 异常

android - 在支持库 28.0.0 中禁用 BottomNavigationView 的 ShiftNode

分辨率为 1920 X 1080 的 Android 模拟器无法打开

android - 如何在android中读取特定的消息正文

android - 使用 SMS Retriever API Android 的 OTP/SMS 自动获取问题

android - GCM : messages by IntentService. 如果应用程序不可见,则不会收到 sendBroadcast

android - 构建项目后 "R cannot be resolved to a variable"错误消失

c# - 以编程方式发送短信

android - 后台应用程序的 GCM 推送通知导致崩溃

android - 奥利奥 : Broadcast receiver Not working