【问题标题】:Receiving SMS on Android App在 Android 应用上接收短信
【发布时间】:2019-11-12 20:36:00
【问题描述】:

我按照教程在我的应用程序上接收 SMS 并阅读它以将 SMSbody 传递给 Toast。 那是 Receiver 类。

public class SmsReciever extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent){
        Bundle bundle= intent.getExtras();
        SmsMessage[] msgs= null;
        String str="";
        if(bundle != null ){
            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();

            }
             Toast.makeText(context, str, Toast.LENGTH_LONG).show();
        }
        }

    }

清单文件

    <receiver android:name="com.msoft.masrooq.SmsReciever">
    <intent-filter>
    <action android:name="android.provider.telephony.SMS_RECIEVED"></action>
    </intent-filter>
    </receiver>
        <uses-permission android:name="android.permission.RECEIVE_SMS"/>
            <uses-permission android:name="android.permission.READ_SMS" />

应用程序启动正常,但没有响应接收短信 它什么也没做。

【问题讨论】:

  • 我有类似的问题。我没有收到任何消息,尽管我认为我已经实现了它工作所需的一切。我不知道这是否可以解决某些问题,但我在清单中的主要活动标签上方声明了接收器,从那时起它就起作用了。希望这能解决某人的问题

标签: java android sms


【解决方案1】:

这是我接收短信的实现。短信可能被分成很多条,注意它是如何处理的。还要检查android:priority 属性。

public class SmsReceiver extends BroadcastReceiver {

    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED)) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                // get sms objects
                Object[] pdus = (Object[]) bundle.get("pdus");
                if (pdus.length == 0) {
                    return;
                }
                // large message might be broken into many
                SmsMessage[] messages = new SmsMessage[pdus.length];
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < pdus.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    sb.append(messages[i].getMessageBody());
                }
                String sender = messages[0].getOriginatingAddress();
                String message = sb.toString();
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
                // prevent any other broadcast receivers from receiving broadcast
                // abortBroadcast();
            }
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.smsreceiver"
    android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity
            android:name=".SmsLoggerActivity"
            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="com.example.smsreceiver.SmsReceiver" android:enabled="true">
            <intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

几点注意事项: 如果您在 xml 中声明您的接收器,那么无论您的应用程序是否启动过,系统都可以使用您的接收器。 由于 Android 1.6 收到的短信通知是作为有序广播发送的,因此您可以使用 &lt;intent-filter&gt;android:priority 属性告诉系统首先将短信发送到您的应用程序(您也可以调用 abortBroadcast() 以便其他应用程序不会接收短信,例如本机短信应用程序)。不要忘记广播接收器有大约 10 秒的时间来执行它的操作,否则它可能会在完成工作之前被提前终止。

【讨论】:

  • +1 请注意,android.permission.SEND_SMS 和 android.permission.RECEIVE_SMS 是不同的。在您的主要活动中,只需创建一个对象 SmsReceiver()。
  • 如何为 MMS 实现这一点?
  • @biegleux Google Play 商店的 Google 管理员认为 RECEIVE_SMS 权限(在您提到的教程中)是危险的。因此,包含该权限的应用程序将被拒绝。然后,开发人员必须向 Google Play 管理员提交表单以供批准。其他开发人员提到这个过程很糟糕,反馈需要数周时间,并且在没有任何解释或一般反馈的情况下被彻底拒绝。关于如何避免的任何想法?
【解决方案2】:

注意:在某些设备上,如果没有意图过滤器中的android:priority="100",您的代码将无法工作:

 <application
 <uses-permission android:name="android.permission.RECEIVE_SMS" />
 <uses-permission android:name="android.permission.READ_SMS" />
 ...
  <receiver
        android:name=".SMSReceiver">
        <intent-filter android:priority="100">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
  </receiver>
 ...
</application>

这里是 Java 代码:

public class SMSReceiver extends BroadcastReceiver {
public static final String ACTION ="android.provider.Telephony.SMS_RECEIVED";
private static final String SMS_SENDER="123456789";

@Override
public void onReceive(Context context, Intent intent) {
        if (intent != null && intent.getAction() != null &&
                ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
            Object[] pduArray = (Object[]) intent.getExtras().get("pdus");
            SmsMessage[] messages = new SmsMessage[pduArray.length];
            for (int i = 0; i < pduArray.length; i++) {
                messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
            }
            // SMS Sender, example: 123456789
            String sms_from = messages[0].getDisplayOriginatingAddress(); 

            //Lets check if SMS sender is 123456789
            if (sms_from.equalsIgnoreCase(SMS_SENDER)) {
                StringBuilder bodyText = new StringBuilder();

                // If SMS has several parts, lets combine it :)
                for (int i = 0; i < messages.length; i++) {
                    bodyText.append(messages[i].getMessageBody());
                }
                //SMS Body
                String body = bodyText.toString();
                // Lets get SMS Code
                String code  = body.replaceAll("[^0-9]", ""); 
            }
      }
 }

【讨论】:

    【解决方案3】:

    广播区分大小写。使用android.provider.Telephony.SMS_RECEIVED 而不是android.provider.telephony.SMS_RECEIVED

    另外,我也有一个类别集,但我不确定它是否是强制性的:

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

    【讨论】:

    • Google Play 商店的 Google 管理员认为 RECEIVE_SMS 权限(在您提到的教程中)是危险的。因此,包含该权限的应用程序将被拒绝。然后,开发人员必须向 Google Play 管理员提交表单以供批准。其他开发人员提到这个过程很糟糕,反馈需要数周时间,并且在没有任何解释或一般反馈的情况下被彻底拒绝。关于如何避免的任何想法?
    猜你喜欢
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多