【问题标题】:SMS Message not received by BroadcastReceiverBroadcastReceiver 未收到 SMS 消息
【发布时间】:2019-07-09 04:54:23
【问题描述】:

我正在尝试编写一个广播接收器来处理收到的 SMS,并启动一个警报对话框来接收来自用户的输入。当主应用程序(MainActivity)关闭(通过滑动)时,这个广播接收器应该可以工作。

接收者根据用户的输入,在通过alert请求用户权限后,将一些内容添加到android文件系统中的文件中。我注意到 BroadcastReceiver 的 onReceive 根本没有被调用

  1. 我正在使用 MainActivity 中的 requestPermissions 从用户那里获取权限
  2. 我正在启动一个名为 ServiceCommunicator 的服务
  3. ServiceCommunicator 注册接收器以收听 SMS
  4. 接收器显示警报消息

我也尝试过不使用 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);

Receiver在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 活动时触发,但在关闭时不触发

【问题讨论】:

    标签: android service broadcastreceiver


    【解决方案1】:

    发生这种情况是因为当您从最近的托盘中滑动应用程序时,它会在许多设备中完全关闭该应用程序,从而导致您的服务也关闭并取消注册您的广播接收器。

    尝试此代码以避免终止您的服务,并确保您拥有自动启动权限和所有其他权限

    将其添加到您的服务中

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

    【讨论】:

    • 对不起,我在第一次编辑时错过了包含 3 行权限。权限在清单中给出,也以编程方式询问
    • 我已经更新了我的答案,以在您的服务中添加此代码,并确保您在设置中为您的应用授予自动启动权限
    • 这在 Android Studio 虚拟设备中有效,但在手机 (Vivo) 中无效
    • 我告诉过你,对于vivo、oppo、redmi等设备,你必须在设置中打开自动启动。这些中国自定义皮肤默认情况下不自动启动。将此答案也标记为正确
    • 感谢 Hritik。默认情况下为应用程序启用自动启动后它正在工作:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多