Android 如何确保广播接收器保持运行并侦听传入的文本消息,而不会被操作系统杀死
我正在编写一个android应用程序,它可以监听传入的文本消息,然后与后端同步。到目前为止,应用程序运行正常,但一段时间后,除非我再次打开应用程序,否则应用程序不会收到任何传入消息。已经探索了各种建议实施JobService或just service的选项,但我做的研究越多,我就越感到困惑。对于JobService,我可以看到它只意味着在一段时间后安排作业,并且一旦作业完成,服务可能会被终止。我需要帮助找到解决问题的最佳方法。下面是我的广播接收器类代码 公共类MessageReceiver扩展了BroadcastReceiver{Android 如何确保广播接收器保持运行并侦听传入的文本消息,而不会被操作系统杀死,android,broadcastreceiver,Android,Broadcastreceiver,我正在编写一个android应用程序,它可以监听传入的文本消息,然后与后端同步。到目前为止,应用程序运行正常,但一段时间后,除非我再次打开应用程序,否则应用程序不会收到任何传入消息。已经探索了各种建议实施JobService或just service的选项,但我做的研究越多,我就越感到困惑。对于JobService,我可以看到它只意味着在一段时间后安排作业,并且一旦作业完成,服务可能会被终止。我需要帮助找到解决问题的最佳方法。下面是我的广播接收器类代码 公共类MessageReceiver扩展了
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;
}
下面是我的舱单
<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>
我不知道您认为您的
MessageListener
对象来自哪里
请理解,您的应用程序进程不会永远运行。一旦您的应用程序的UI移动到后台,。这将清除任何可能存在的MessageListener
对象
因此,最有可能发生的情况是,您设置了此MessageListener
,它会工作一段时间,直到原始进程终止。未来的SMS消息将为您的应用程序启动一个新进程,但您不再拥有MessageListener
,因此您的工作无法完成
取而代之的是,去掉
MessageListener
和任何你用来保存引用的static
字段。让你的BroadcastReceiver
使用WorkManager
做后台工作,你的Worker
可以自己处理所有事情,而不依赖应用程序nec的任何活动等已在当前进程中运行。您在何处以及如何注册MessageReceiver
?我已创建了一个类(MessageReceiver)实现广播接收器的。我有一个侦听器接口,在其中传递接收到的TextMessage对象。抱歉,这不是我要问的。清单中是否有指向MessageReceiver
的
元素?或者您正在调用registerReceiver()
在哪里注册MessageReceiver
?我在清单上有它。注意到。但我仍然对广播接收器有一些担心,因为在某个时候,如果广播接收器的onReceive方法在一段时间后没有被调用,应用程序可能会被杀死,有没有办法克服这个问题。我问这个问题是因为我想知道什么时候用户安装此应用程序时,它应该开始拦截所有传入的消息,而不需要用户继续重新启动应用程序。@杰克:您的接收者已在清单中注册。即使您没有运行进程(“应用程序可能会被终止”),您仍将接收广播。Android将为您提供一个新的进程,然后调用onReceive()在这个过程中,你的MessageReceiver
的。但是,在这一点上,你没有MessageListener
。这就是为什么你需要摆脱MessageListener
,让MessageReceiver
不要假设你的应用程序的某个前一个过程中有任何东西在内存中。现在,这对我来说很有意义。非常重要谢谢。这就是我出错的地方。很快,我删除了侦听器,一切正常,但当我关闭android系统时,广播接收器不活动,在我启动应用程序之前无法接收任何文本。@Jack:你可能无法从广播接收器
可靠地显示土司
。And网络I/O需要卸载到WorkManager
、JobIntentService
、或前台服务
。不仅在接收广播之前,您的应用程序进程可能不存在,而且在onReceive()之后,您的应用程序进程可能会在几毫秒后关闭
返回。WorkManager
和其他列出的选项将有助于解决此问题。如果仍然存在问题,请提出一个新的堆栈溢出问题,显示当前代码,并提供您看到(和未看到)的详细信息。
<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>