繁体   English   中英

如何在广播接收器中获取短信数据

[英]How to get sms data in a Broadcast receiver

我需要为我的用户提供一个经过验证的电话号码,但是经过研究后,似乎没有可靠的方法可以从设备中获取电话号码。 我见过几次建议是发送一条短信,然后在广播接收器中捕获该短信,然后根据编码意图解析电话号码。 我已经看到了这个问题: 接收到的广播后,我无法从意向获取数据 ,而这一个 ,但他们并没有解决我的问题。

目前,我正在使接收器工作,但无法获取有关SMS消息的任何数据,该数据大概可以通过意图进行访问。

这是用户按下“发送”按钮时触发的代码:

    btnSend.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                String SENT = "sent";
                String DELIVERED = "delivered";
                Intent sentIntent = new Intent(SENT);

                /*Create Pending Intents*/
                PendingIntent sentPI = PendingIntent.getBroadcast(
                        getApplicationContext(), 0, sentIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT);

                /* Register for SMS send action */
                registerReceiver(new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        try {
      --->                  **SmsMessage[] smsMessage = Telephony.Sms.Intents.getMessagesFromIntent(intent);**
                            String messageBody = smsMessage[0].getMessageBody();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        int resultcode = getResultCode();
                        Log.d("  RESULT=", Integer.toString(resultcode));
                    }

                }, new IntentFilter(SENT));

                SmsManager smsManager = SmsManager.getDefault();

                if ((ContextCompat.checkSelfPermission(getApplicationContext(),
                        Manifest.permission.SEND_SMS) !=
                        PackageManager.PERMISSION_GRANTED) ||
                        (ContextCompat.checkSelfPermission(getApplicationContext(),
                                Manifest.permission.RECEIVE_SMS) !=
                                PackageManager.PERMISSION_GRANTED)){
                    ActivityCompat.requestPermissions(SMSActivity.this,
                            new String[] {
                                    Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS
                            }, 1);
                }
                smsManager.sendTextMessage(phoneNo.getText().toString(), null,
                                                msg.getText().toString(), sentPI, null);
            } catch (Exception ex) {
                Toast.makeText(getApplicationContext(),
                        ex.getMessage(), Toast.LENGTH_LONG)
                        .show();
                ex.printStackTrace();
            }
        }
    });

调用getMessagesFromIntent()(粗体行)时,将引发一个异常,如“ onReceive(SMSActivity.java:60)”中列出的那样:Intent不为null,因此看来“ null array”是内部的到getMessagesFromIntent。

W/System.err: java.lang.NullPointerException: Attempt to get length of null array
W/System.err:     at android.provider.Telephony$Sms$Intents.getMessagesFromIntent(Telephony.java:1345)
W/System.err:     at com.jdot.jsontest.SMSActivity$1$1.onReceive(SMSActivity.java:60)
W/System.err:     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:993)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err:     at android.os.Looper.loop(Looper.java:158)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7224)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

我认为我可能有与权限相关的问题。 我已将此添加到清单中:

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

我也看过几次这个清单,但是我不知道如何命名MyBroadcastListener,因为它不是像我所看到的例子那样的类。

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

最后,我在onReceive()主体中尝试了以下代码块(作为替代)。 尽管intent.getExtras()返回Bundle,但调用bundle.get(“ pdus”)返回null,则其他所有操作都会失败。

Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
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 += "SMS from " + msgs[i].getOriginatingAddress();
              str += " :";
              str += msgs[i].getMessageBody().toString();
              str += "\n";
    }
//---display the new SMS message---
     Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}

我的问题是:

  1. 我的清单中是否需要Receiver / Intent-filter块,如果需要,如何在第一行中命名侦听器?
  2. 我无法在onReceive()中收到传入消息的副本的可能原因是什么,我该怎么做才能更正它?
  3. 我是否需要发送消息并在onReceive()中“捕获”以便可靠地获取设备的电话号码,还是可以请求用户读取SMS的权限,而只是阅读第一条消息以获取传入的电话号码?

请注意,我已经阅读了所有类似的问题,但没有找到答案。


这是您的问题:

registerReceiver(..., new IntentFilter(SENT));

您正在为要用于已发送确认的操作而不是针对SMS_RECEIVED操作(该操作是在消息到达时广播)注册该Receiver。

发送的 PendingIntent用于确认消息已成功离开设备。 由此产生的Intent上没有任何消息PDU,这就是您崩溃的原因。

如果要使用API​​ 19或更高版本进行编译,则需要为其注册传入SMS接收器的操作是"android.provider.Telephony.SMS_RECEIVED"或常量Telephony.Sms.Intents.SMS_RECEIVED_ACTION


要解决特定问题:

  1. 我的清单中是否需要Receiver / Intent-filter块,如果需要,如何在第一行中命名侦听器?

在清单中注册Receiver,即使您的应用尚未运行,也可以在前台接收消息。 如果您不需要这样做,则不必在清单中注册。 但是,如果用户在收到消息之前离开了您的Activity ,则暂停的Activity将无法广播。

处理它的“最安全”方法是在清单中注册,但是在此注册的是类,而不是动态实例。 您将需要创建一个MyBroadcastListener类,并在收到消息后以某种方式通知Activity 例如,使用startActivity()LocalBroadcastManager或其他一些事件总线实现等。

  1. 我无法在onReceive()中收到传入消息的副本的可能原因是什么,我该怎么做才能更正它?

如上所述,在sendTextMessage()调用中传递的PendingIntent用于发送确认。 其产生的Intent将不会包含传入消息。 您只需要收听正确的广播。

  1. 我是否需要发送消息并在onReceive()中“捕获”以便可靠地获取设备的电话号码,还是可以请求用户读取SMS的权限,而只是阅读第一条消息以获取传入的电话号码?

您实际上需要发送一条消息。 收到的邮件将不会附加收件人号码。

试试这个。希望对您有帮助。

public class IncomingSMSReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Bundle b = intent.getExtras();
    try {
        if (b != null) {
            Object[] pdusObj = (Object[]) b.get("pdus");

            for (int i = 0; i < pdusObj.length; i++) {
                SmsMessage currentMessage = SmsMessage
                        .createFromPdu((byte[]) pdusObj[i]);
                String phoneNumber = currentMessage
                        .getDisplayOriginatingAddress();
                String senderNum = phoneNumber;
                String message = currentMessage.getDisplayMessageBody();

                if (senderNum .equals("VK-VERIFY")) 
                 {
                        MainActivity Sms = new MainActivity();
                        Log.d("TAG",""+message);
                        Sms.recivedSms(message);
                 }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}}

Android清单

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nitish.incomingsms"
android:versionCode="1"
android:versionName="1.0" >

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

<uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="16" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

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

在message变量中,您将获得整个messagebody。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM