如何让Android应用在关闭后仍正常运行?前台Service被划杀问题求解
问题修复方案
你目前遇到的服务被杀死的问题,可按以下步骤逐一修复:
- 修复高版本安卓前台服务启动逻辑
安卓8.0及以上系统要求启动前台服务必须调用startForegroundService(),你当前直接使用startService()会导致高版本系统中服务启动失败被强制清理。
修改Application类中服务启动代码:
class App : Application() { override fun onCreate() { super.onCreate() val serviceIntent = Intent(this, BackgroundWorkService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(serviceIntent) } else { startService(serviceIntent) } } }
- 修复PendingIntent可变性标记问题
安卓12及以上系统要求PendingIntent必须显式指定可变性标记,你当前传入0作为标记会触发崩溃,导致服务无法正常启动。
修改startServiceForeground()中的PendingIntent构造逻辑:
private fun startServiceForeground() { val notificationIntent = Intent(this, MainActivity::class.java) val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE) } else { PendingIntent.getActivity(this, 0, notificationIntent, 0) } // 剩余原有逻辑不变 }
- 补全Manifest中Service的必要配置
安卓12及以上要求前台服务必须声明foregroundServiceType属性,同时你的服务不需要对外导出,exported="true"存在安全风险,修改service配置:
<service android:name=".app.BackgroundWorkService" android:enabled="true" android:exported="false" android:foregroundServiceType="phoneCall" />
如果是安卓14及以上 target,还需要补充权限声明:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
- 替换实现逻辑,提升后台存活率
来电监听场景不需要常驻前台服务,更合理的方案是静态注册来电广播,系统收到来电时会主动唤醒你的应用执行逻辑,不需要保持进程常驻,被系统杀死的概率更低:
- 新增来电广播接收器:
class PhoneCallReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED) { val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE) val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) if (state == TelephonyManager.EXTRA_STATE_RINGING && incomingNumber != null) { // 此处匹配你自定义的号码名单,匹配则切换静音/勿扰模式 val audioManager = context?.getSystemService(Context.AUDIO_SERVICE) as AudioManager audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT } } } }
- Manifest中注册广播:
<receiver android:name=".PhoneCallReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver>
- 补全特殊权限申请与ROM权限引导
- 切换勿扰模式需要的
ACCESS_NOTIFICATION_POLICY是特殊权限,仅在Manifest声明无效,需要主动跳转系统设置引导用户授权:
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !notificationManager.isNotificationPolicyAccessGranted) { val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS) startActivity(intent) }
- 国内厂商定制ROM(小米、华为、OPPO、vivo等)默认会限制应用自启动、后台运行权限,需要引导用户手动开启:自启动权限、后台活动权限、加入电池优化白名单,否则无论服务怎么配置,划掉APP后都会被系统强制杀死。
内容的提问来源于stack exchange,提问作者FarVoyager
相关产品推荐
相关产品推荐

