Android 9上试遍所有保活方案 前台Service仍被销毁无法持续监听传感器
Android 9 设备前台Service持续监听传感器失效问题
需求说明
- 实现的Service搭载
SensorEventListener,需要持续监听设备3个传感器的数值变化 - 服务需要在主Activity切后台、被用户主动杀死的场景下保持运行
- 已明确知晓长期后台运行的功耗影响,当前需求阶段暂不考虑功耗约束
已尝试的全部方案
以下所有方案均已逐一验证,未达到预期效果:
- 按谷歌官方规范适配系统版本启动服务,Android 8.0及以上版本调用
startForegroundService,低版本调用startService:
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){ Intent i = new Intent(context, myService.class); startForegroundService(i); }else { Intent i = new Intent(context, myService.class); startService(i); }
- 在Service的
onCreate生命周期末尾调用startForeground挂载常驻通知:
Notification nf=GetNotification(); startForeground(NOTIFICATION_ID, nf);
- 单独及组合重写
onDestroy、onTaskRemoved生命周期方法,发送自定义广播触发服务重启:
@Override public void onTaskRemoved(Intent rootIntent) { super.onTaskRemoved(rootIntent); Intent tnt=new Intent("com.myAppPackage.appName.actionName"); sendBroadcast(tnt); } public void onDestroy() { super.onDestroy(); Intent tnt=new Intent("com.myAppPackage.appName.actionName"); sendBroadcast(tnt); }
- 实现自定义广播接收器,收到对应广播后重新拉起服务:
private class clsKeepServiceAlive extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){ Intent i = new Intent(context, myService.class); startForegroundService(i); }else { Intent i = new Intent(context, myService.class); startService(i); } } } private clsKeepServiceAlive m_keepServiceAlive=new clsKeepServiceAlive();
- 在Service的
onCreate中动态注册上述广播接收器,同时绑定自定义动作、开机完成、锁屏完成的IntentFilter:
IntentFilter iflt4=new IntentFilter(); iflt4.addAction("com.myAppPackage.appName.actionName"); iflt4.addAction("android.intent.action.LOCKED_BOOT_COMPLETED"); iflt4.addAction("android.intent.action.BOOT_COMPLETED"); registerReceiver(m_keepServiceAlive, iflt4);
- 在Manifest中配置Service属性,设置独立进程、免随任务移除停止、直接启动感知权限:
<service android:name=".myService" android:enabled="true" android:exported="false" android:process=":myservicename" android:directBootAware="true" android:label="@string/app_name" android:stopWithTask="false" />
实际运行异常表现
- 在Service的
onDestroy回调中植入埋点逻辑,服务销毁时将信息写入本地数据库,精准记录服务销毁时机 - 应用切后台、被用户手动杀死的初始阶段,可正常显示前台常驻通知,应用图标上可看到通知角标
- 应用切后台约20分钟后,常驻通知消失、通知角标同步消失,服务已被系统销毁,下次打开应用时可查询到之前写入的服务销毁日志
- 所有网上可查询到的Service长期运行方案,在当前测试的Android 9设备上全部失效
应用构建基础配置
对应的Gradle配置片段如下:
android { compileSdkVersion 30 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.myAppPackage.appName" minSdkVersion 23 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } }
内容的提问来源于stack exchange,提问作者R1349
相关产品推荐
相关产品推荐

