BroadcastReceiver 未收到 SMS 消息
SMS Message not received by BroadcastReceiver
我正在尝试编写一个广播接收器来处理收到的 SMS,并启动一个警报对话框来接收来自用户的输入。当主应用程序 (MainActivity) 关闭(通过滑动)时,此广播接收器有望工作。
根据用户的输入,接收方在通过警报请求用户许可后,将一些内容添加到 android 文件系统中的文件中。我注意到根本没有调用 BroadcastReceiver 的 onReceive
- 我正在使用 MainActivity 中的 requestPermissions 从用户那里获取权限
- 我正在启动一个名为 ServiceCommunicator 的服务
- ServiceCommunicator 注册接收器以收听 SMS
- 接收方显示警告消息
我也试过没有 ServiceCommunicator(Receiver 是在 MainActivity 本身注册的)
在上述两种情况下,都不会触发接收器的 onCreate。接收器在 adb shell 命令中列出:
adb shell cmd package query-receivers --brief -a android.provider.Telephony.SMS_RECEIVED
MainActivity 具有以下作为 onCreate 方法的一部分:
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
android.Manifest.permission.RECEIVE_SMS,
android.Manifest.permission.SEND_SMS,
};
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
Intent serviceIntent = new Intent(this, ServiceCommunicator.class);
startService(serviceIntent);
...
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch(requestCode)
{
case MY_PERMISSIONS_REQUEST_RECEIVE_SMS:
{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "Thanks for SMS receive permissions", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this, "SMS can't be received", Toast.LENGTH_LONG).show();
}
break;
}
case MY_PERMISSIONS_REQUEST_SEND_SMS:
{
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Thanks for SMS send permissions",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"SMS can't be sent", Toast.LENGTH_LONG).show();
}
break;
}
}
return;
}
ServiceCommunicator 具有以下内容:
receiverIntentFilter = new IntentFilter();
receiverIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
myReceiver = new MyReceiver();
// Register SMS event receiver
registerReceiver(myReceiver, receiverIntentFilter);
接收方在 onReceive 中有以下内容:
if (intent.getAction() == "android.provider.Telephony.SMS_RECEIVED")
{
...
Intent alertDialogIntent = new Intent(context, AlertDialogActivity.class);
alertDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alertDialogIntent.putExtra("ALERT_MSG", alertMsg);
alertDialogIntent.putExtra("MESSAGE", "\n" + msg);
context.startActivity(alertDialogIntent);
}
AlertDialogActivity 具有以下内容:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setTitle("Add information to system?")
.setMessage(alertMsg)
...
Manifest.xml 有以下内容。更新了文件(抱歉,之前错过了):
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<receiver android:priority="2147483647" android:name=".MyReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED">
</action>
</intent-filter>
</receiver>
<service android:process="com.example.rtien.ServiceCommunicator" android:enabled="true" android:exported="true" android:stopWithTask="false" android:name="com.example.rtien.ServiceCommunicator" />
<activity android:name=".MainActivity" android:theme="@style/Theme.AppCompat">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
预期结果:当 MainActivity 关闭时,接收器应该 运行 在后台。应该触发接收器中的 onReceive 方法。应显示警报消息,并将数据添加到文件
观察结果:接收者的onReceive在MainActivity活动时触发,但在关闭时不触发
发生这种情况是因为当您从最近托盘中滑动应用程序时,它会在许多设备上完全关闭该应用程序,从而导致您的服务也关闭并注销您的广播接收器。
尝试此代码以避免终止您的服务,并确保您拥有 auto-start 权限和所有其他权限
将其添加到您的服务中
@Override
public void onTaskRemoved(Intent rootIntent) {
try {
Intent restartService = new Intent(getApplicationContext(),this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
} catch (Exception e) {
e.printStackTrace();
}
}
我正在尝试编写一个广播接收器来处理收到的 SMS,并启动一个警报对话框来接收来自用户的输入。当主应用程序 (MainActivity) 关闭(通过滑动)时,此广播接收器有望工作。
根据用户的输入,接收方在通过警报请求用户许可后,将一些内容添加到 android 文件系统中的文件中。我注意到根本没有调用 BroadcastReceiver 的 onReceive
- 我正在使用 MainActivity 中的 requestPermissions 从用户那里获取权限
- 我正在启动一个名为 ServiceCommunicator 的服务
- ServiceCommunicator 注册接收器以收听 SMS
- 接收方显示警告消息
我也试过没有 ServiceCommunicator(Receiver 是在 MainActivity 本身注册的)
在上述两种情况下,都不会触发接收器的 onCreate。接收器在 adb shell 命令中列出:
adb shell cmd package query-receivers --brief -a android.provider.Telephony.SMS_RECEIVED
MainActivity 具有以下作为 onCreate 方法的一部分:
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
android.Manifest.permission.RECEIVE_SMS,
android.Manifest.permission.SEND_SMS,
};
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
Intent serviceIntent = new Intent(this, ServiceCommunicator.class);
startService(serviceIntent);
...
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch(requestCode)
{
case MY_PERMISSIONS_REQUEST_RECEIVE_SMS:
{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "Thanks for SMS receive permissions", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this, "SMS can't be received", Toast.LENGTH_LONG).show();
}
break;
}
case MY_PERMISSIONS_REQUEST_SEND_SMS:
{
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Thanks for SMS send permissions",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"SMS can't be sent", Toast.LENGTH_LONG).show();
}
break;
}
}
return;
}
ServiceCommunicator 具有以下内容:
receiverIntentFilter = new IntentFilter();
receiverIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
myReceiver = new MyReceiver();
// Register SMS event receiver
registerReceiver(myReceiver, receiverIntentFilter);
接收方在 onReceive 中有以下内容:
if (intent.getAction() == "android.provider.Telephony.SMS_RECEIVED")
{
...
Intent alertDialogIntent = new Intent(context, AlertDialogActivity.class);
alertDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alertDialogIntent.putExtra("ALERT_MSG", alertMsg);
alertDialogIntent.putExtra("MESSAGE", "\n" + msg);
context.startActivity(alertDialogIntent);
}
AlertDialogActivity 具有以下内容:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setTitle("Add information to system?")
.setMessage(alertMsg)
...
Manifest.xml 有以下内容。更新了文件(抱歉,之前错过了):
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<receiver android:priority="2147483647" android:name=".MyReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED">
</action>
</intent-filter>
</receiver>
<service android:process="com.example.rtien.ServiceCommunicator" android:enabled="true" android:exported="true" android:stopWithTask="false" android:name="com.example.rtien.ServiceCommunicator" />
<activity android:name=".MainActivity" android:theme="@style/Theme.AppCompat">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
预期结果:当 MainActivity 关闭时,接收器应该 运行 在后台。应该触发接收器中的 onReceive 方法。应显示警报消息,并将数据添加到文件
观察结果:接收者的onReceive在MainActivity活动时触发,但在关闭时不触发
发生这种情况是因为当您从最近托盘中滑动应用程序时,它会在许多设备上完全关闭该应用程序,从而导致您的服务也关闭并注销您的广播接收器。
尝试此代码以避免终止您的服务,并确保您拥有 auto-start 权限和所有其他权限
将其添加到您的服务中
@Override
public void onTaskRemoved(Intent rootIntent) {
try {
Intent restartService = new Intent(getApplicationContext(),this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
} catch (Exception e) {
e.printStackTrace();
}
}