web-dev-qa-db-ja.com

BroadcastReceiver SMS_Receivedが新しいデバイスで機能しない

いくつかのリソースと質問を検討した後も、着信するSMSメッセージの検出に問題があります。

以下のコードは基本を示しています:

トーストonReceiveを表示するブロードキャストレシーバークラス

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で、デフォルトのメッセンジャーアプリがインストールされています(私もハングアウトを試しました)。アプリはまだ私のトーストを表示しません。古いSamsungデバイスを試した後、トーストは正しく印刷されました。

優先課題

6PにManifest Viewerというアプリをインストールしました。これにより、デバイスにインストールされているアプリのmanifest.xmlを確認できます。 SMSタグの受信者について、メッセンジャーとハングアウトの両方のマニフェストを確認したところ、どちらも2147483647の優先度を指定していることがわかりました。これらのメッセンジャーアプリはどちらも優先度を最大にしたようです、そしていったんメッセージを消費すると、他のアプリケーションが介入することはできません。これらはサードパーティではなく、ストックのGoogleアプリであることに注意してください。

この時点で、私は次の点についてかなり混乱しています。

  • なぜこれを行うのですか?
  • それをバイパスする方法?

どうもありがとう

11
Khorkhe

問題は解決しました。この問題は優先度では発生しませんでしたが、私の電話はNexus 6P(別名API 23)でした。

Manifest.xmlだけで権限を提供するだけでは不十分で、ランタイム権限リクエストのコードを追加する必要がありました。参照 ランタイム権限についてはAndroidのドキュメント

このコードを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");
    }
}
31
Khorkhe

実装がこのようになっていることを確認してください。

SMSレシーバークラス

    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>

必ず独自に定義したパッケージを使用してください。ここで定義されているパッケージはダミーです。

2
Adnan Amjad