首页 > 解决方案 > 如何确保广播接收器保持运行并侦听传入的文本消息而不会被操作系统杀死

问题描述

我正在编写一个 android 应用程序来侦听传入的短信,然后与后端同步。到目前为止,该应用程序运行正常,但一段时间后,除非我再次打开该应用程序,否则该应用程序不会收到任何传入消息。已经探索了各种建议实施 JobService 或只是服务的选项,但是做的研究越多,我就越感到困惑。对于 JobService,我可以看到它仅意味着在一段时间后安排作业,并且一旦作业完成,服务可能会被终止。我需要帮助以找到解决问题的最佳方法。下面是我的广播接收器类的代码;

公共类 MessageReceiver 扩展 BroadcastReceiver {

private static MessageListener messageListener;
Handler mHandler;

private static final String TAG = "MessageReceiver";

public MessageReceiver() {

}

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onReceive(final Context context, Intent intent) {

   if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
       final Bundle data = intent.getExtras();
       HandlerThread bgHandlerThread=new HandlerThread("MyCoolBackgroundThread");
       bgHandlerThread.start();
       mHandler=new Handler(bgHandlerThread.getLooper());

       Runnable backgroundRunnable = new Runnable() {
           @Override
           public void run() {
               passReceivedMsg(data);
           }
       };
       mHandler.post(backgroundRunnable);

   }

}

我已经实现了一个接口,我在其中传递接收到的 TextMessage 对象,

    private void passReceivedMsg(final Bundle bundleData) {
    if (bundleData !=null ){
        try {
            final Object[] pdusObj = (Object[]) bundleData.get("pdus");
            if (pdusObj != null) {
                for (int i = 0; i < pdusObj.length; i++) {
                    SmsMessage currentMessage =
                            SmsMessage.createFromPdu((byte[]) pdusObj[i]);
                    Log.d(TAG, "run: currentMessage: "+currentMessage);

                    messageListener.getReceivedMessage(currentMessage);
                    Log.d(TAG, "handleMessage: message "+currentMessage);

                }
            }
        }
        catch (Exception e){
            Log.d(TAG, "onReceive: Error occurred "+e);

        }

    }

}

public static void bindListener (MessageListener listener){
        messageListener = listener;
}

MessageListener 如下;

public interface MessageListener {
    void getReceivedMessage(SmsMessage message);
}

下面是我的清单

       <receiver
            android:name=".utils.MessageReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">

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

标签: androidbroadcastreceiver

解决方案


我不知道你认为你的MessageListener对象来自哪里。

请理解您的申请流程不会永远运行。只要您的应用程序的 UI 移到后台,Android 就可以随时终止您的进程。这消除了任何MessageListener可能存在的对象。

因此,最有可能发生的事情是您设置了 this MessageListener,并且它工作了一段时间,直到原始进程终止。未来的 SMS 消息将为您的应用程序启动一个新流程,但您不再拥有您的MessageListener,因此您的工作无法完成。

相反,摆脱你用来保存对它的引用的MessageListener任何字段。static让您BroadcastReceiver使用WorkManager它来完成它的后台工作,您Worker可以自己处理所有事情,而不依赖于您的应用程序的任何活动等,这些活动必须在当前进程中运行。


推荐阅读