推送消息无法立即启动服务
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了推送消息无法立即启动服务相关的知识,希望对你有一定的参考价值。
上下文
我们正在开发一个应用程序,应该执行以下操作:
- 用户安装应用程序,注册并关闭应用程序
- 每年一次或两次,管理员向包含地理围栏的用户发送优先级较高的Firebase数据消息
- FCM消息启动一个JobService,用于定位电话的位置
- 如果手机在给定区域内,则启动“活动”并开始用户交互
- 如果手机在该区域之外,则服务停止并且用户永远不会受到干扰
我根据发现here的Firebase推送示例开发了应用程序
问题
该应用程序在我的旧手机上工作正常,但在我的新测试手机(android 8.1.0,LineageOS 15.1)上,当手机处于睡眠模式时,我们遇到了问题。在这种情况下,FCM消息立即到达,但是一旦电话解锁,服务就会首先启动。所以消息卡在2.和3之间。
我们需要应用程序立即响应 - 而不是在用户决定在2小时后使用他的手机时。
我认为问题是由于android 6引入了Doze mode。我尝试通过在设置 - >电池 - >电池优化中将应用添加到白名单来解决它,但这并没有解决问题。
问题
- 打盹模式是否会将我的应用程序延迟到2.和3之间?如果是这样,当应用程序在白名单中时为什么没有解决?
- 有没有其他方法可以立即启动位置服务? This帖子表明前台服务可以做到这一点,但这需要显示一个与5分开的notification。
- 除了白名单和前台服务之外,还有其他方法可以立即启动我的服务吗?
是!你是对的,这可能是由于API 23 Marshmallow中引入的Doze and App Standby功能。
如documentation中所述,系统会忽略唤醒锁,系统不允许JobScheduler
运行,这有效地阻止了您的应用程序运行作业。
一个简单而有效的解决方法是在正常的background service中运行位置检测例程,并在接收FCM推送时使用startService()
启动它。
请注意,您可能仍需要将应用程序列入白名单,因为正如此处另一篇文章中所述,只有列入白名单的应用程序才能使用网络并保留部分唤醒锁定。
打盹模式是否会将我的应用程序延迟到2.和3之间?
从documentation打盹模式影响网络访问和阻止JobScheduler
。
如果是这样,当应用程序在白名单中时为什么没有解决?
同样来自documentation:白名单中的应用可以使用网络并在Doze和App Standby期间保持部分唤醒锁定。但是,其他限制仍然适用于列入白名单的应用,就像对其他应用一样。
因此阻止JobScheduler
仍然适用。
有没有其他方法可以立即启动位置服务?这篇文章表明前台服务可以做到这一点,但这要求显示一个以5为中断的通知。
忽略电池优化(用于互联网访问)与AlarmManager
与setAndAllowWhileIdle()
或setExactAndAllowWhileIdle()
组合应该工作。
忽略电池优化时要小心
除非应用程序的核心功能受到不利影响,否则Google Play政策会禁止应用程序直接豁免Android 6.0+(Doze和App Standby)中的电源管理功能。
我认为这里的一个重要问题是:你真的需要立即执行JobScheduler
。
如果用户将设备拔出并静止一段时间,屏幕关闭,设备将进入打盹模式。
如果设备处于打盹模式,则表示用户未使用它。
如果手机在给定区域内,则启动“活动”并开始用户交互
这是步骤打盹块
我们需要应用程序立即响应 - 而不是在用户决定在2小时后使用他的手机时。
如果设备处于Doze状态,则表示用户未与其进行交互。即使您显示Activity
用户没有使用手机,他会在2小时后开始使用它时看到它:)
我仍然没有尝试,但你可能会使用WakefulBroadcastReceiver:https://developer.android.com/training/scheduling/wakelock.html https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html
根据此链接,您应将接收方声明为:
public class YourReceiver extends WakefulBroadcastReceiver {
可能你的接收器已经是WakefulBroadcastReceiver,因为通知正在显示..
在接收器中,您使用以下命令启动服务(您的服务必须是IntentService):
startWakefulService(context, your service);
最后,记得在服务中释放唤醒锁:
@Override
protected void onHandleIntent(Intent intent) {
<Your_broadcast_receiver_class>.completeWakefulIntent(intent);
}
我希望它有所帮助
以上是关于推送消息无法立即启动服务的主要内容,如果未能解决你的问题,请参考以下文章