【问题标题】:BroadcastReceiver SMS_Received not working on new devicesBroadcastReceiver SMS_Received 在新设备上不起作用
【发布时间】:2016-06-28 11:08:52
【问题描述】:

在查看了几个资源和问题后,我仍然面临检测传入 SMS 消息的问题。

下面的代码显示了基础知识:

在接收时显示 toast 的广播接收器类

public class IncomingSms extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "something received", Toast.LENGTH_SHORT).show();
    }
}

带有注册接收者和权限的简单清单

<application
    <receiver 
        android:name=".IncomingSms"
        android:permission="android.permission.BROADCAST_SMS"
        android:exported="true">

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

</application>

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

上面的代码声明并注册了接收者,并拥有适当的权限。此外,优先级设置为 MAX_INT,即 2147483647。

我的设备是 Nexus 6P,安装了默认的 Messenger 应用(我也尝试过环聊)。该应用程序仍然没有显示我的祝酒词。在旧款三星设备上试用后,吐司打印正确。

优先级问题

我在 6P 上安装了一个名为 Manifest Viewer 的应用程序,它允许我查看安装在我的设备上的应用程序的 manifest.xml。我检查了 Messenger 和 Hangouts 的清单,以获取 SMS 标签的接收者,发现它们都指定了 2147483647 的优先级。似乎这两个 Messenger 应用程序的优先级都达到了最大值,一旦它们消费了消息,它们不允许其他应用程序干预。请注意,这些是现有的 Google 应用,而不是第 3 方。

在这一点上,我很困惑:

  • 他们为什么要这样做?
  • 如何绕过它?

非常感谢

【问题讨论】:

    标签: android broadcastreceiver sms android-permissions


    【解决方案1】:

    好的,问题已解决。 问题不在于优先级,而在于我的手机是 Nexus 6P(又名 API 23)。

    仅在 manifest.xml 中提供权限是不够的,我必须为运行时权限请求添加代码。见Android documentation for runtime permissions

    将此代码添加到您的 MainActiviy:

    ActivityCompat.requestPermissions(this, 
                new String[]{Manifest.permission.RECEIVE_SMS},
                MY_PERMISSIONS_REQUEST_SMS_RECEIVE);
    

    在 MainActivity 类的顶部定义它:

    private int MY_PERMISSIONS_REQUEST_SMS_RECEIVE = 10;
    

    并且还要添加这个覆盖:

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_PERMISSIONS_REQUEST_SMS_RECEIVE) {
            // YES!!
            Log.i("TAG", "MY_PERMISSIONS_REQUEST_SMS_RECEIVE --> YES");
        }
    }
    

    【讨论】:

    • 还有 Nexus 6P。谢谢我需要的东西!谢谢
    • 谢谢你,很棒的帖子,很有帮助。虽然我的印象是问题更多与 API 级别 23 相关,而不是 Nexus 设备。也许你应该注意到最后一个覆盖并不是真正需要的,只是为了像我这样的代码复制僵尸;-)
    • @anhoppe 是的,如果您在 api 版本 >= 23 上运行,他们应该提醒您需要这样做
    • 这解决了我的问题——我只请求READ_SMS 权限,而不是RECEIVE_SMS 权限。尽管我遵循了关于 Android Authority 的教程!
    • 精彩的答案!它发生在 API 级别 30 像素设备中。
    【解决方案2】:

    请确保您的实现是这样的。

    短信接收类

        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();
                    }
                }
            }
        }
    

    Manifest.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
               // your activity
            </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>
    

    确保您使用自己定义的包。此处定义的包是虚拟的。

    【讨论】:

    • 我想首先确保在“onReceive”中检测到任何内容,然后再深入研究更详细的实现。我试过你的sn-ps只是为了确认,仍然没有输出。我仍然认为这与 Nexus 的股票应用程序设置的优先级有关。
    • 如果有帮助,请查看本教程。 androidexample.com/…
    • 只是为了检查。从设置中强制关闭两个短信应用程序。然后测试您的应用。
    • 问题不在于广播注册的实现或在清单中的注册。您需要额外的应用权限,例如推荐的最佳答案
    猜你喜欢
    • 2016-06-13
    • 1970-01-01
    • 2022-11-15
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多