いくつかのリソースと質問を検討した後も、着信する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アプリであることに注意してください。
この時点で、私は次の点についてかなり混乱しています。
どうもありがとう
問題は解決しました。この問題は優先度では発生しませんでしたが、私の電話は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");
}
}
実装がこのようになっていることを確認してください。
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>
必ず独自に定義したパッケージを使用してください。ここで定義されているパッケージはダミーです。