Я написал службу переднего плана, которая работает правильно для всех версий ОС ниже, чем Oreo.От Oreo процесс приложения убивается после 5 минут закрытия и удаления приложения из последних.
Согласно документации разработчика Android для ограничения выполнения фона ОС не должна убивать приложение, для которого служба переднего планаработает, и уведомление отображается в окне уведомлений.
Согласно руководствам по документации для разработчиков.Я следовал приведенным ниже шагам, чтобы запустить службу переднего плана.
- Служба переднего плана запускается с помощью
startForegroundService()
метода - В течение 5 секунд после запуска службы для службы отображается уведомление с использованием
startForeground()
- Возврат
START_STICKY
из onStartCommand()
из service
Я сталкиваюсь с этой проблемой на следующих телефонах:
- OnePlus 5T
- Vivo
- Oppo
- Mi
Что я пытался предотвратить уничтожение службы переднего плана?
- Отключить оптимизация батареи для приложения, показывающая системное диалоговое окно для пользователя, чтобы отключить режим ожидания.
Что я пытался перезапустить на переднем плане-сервис?
- Используется
AlarmManager
для перезапуска службы из onTaskRemoved ().Пожалуйста, проверьте эту ссылку для получения более подробной информации.
Насколько я понимаю, эти производители настроили AOSP и не соблюдают руководящие принципы ОС для запуска службы переднего плана.Возможно, эти производители сделали это из-за того, что предоставили пользователям длительное время автономной работы.
Класс обслуживания переднего плана
class DataCaptureService : Service() {
private var isServiceStarted = false
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakelockTag123").apply {
acquire()
}
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val serviceAction = intent?.action
LogUtils.logD("OnStartCommand(). Action=$serviceAction")
if (Constants.INTENT.ACTION_STOP_SERVICE == serviceAction) {
LogUtils.logD("Stopping data capture service")
stopForeground(true)
stopSelf()
} else if (Constants.INTENT.ACTION_START_SERVICE == serviceAction && !isServiceStarted) {
LogUtils.logD("Starting data capture service")
isServiceStarted = true
// Here showing notification using a utility method (startForeground(id, notification))
createNotification(this)
// Doing some stuff here
----------------------
//
}
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
if (isServiceStarted) {
LogUtils.logD("onDestroy of DataCaptureService method is invoked")
// Doing some stuff here
----------------------
//
isServiceStarted = false
if (wakeLock.isHeld) {
wakeLock.release()
}
}
}
override fun onTaskRemoved(rootIntent: Intent?) {
LogUtils.logD("onTaskRemoved of DataCaptureService method is invoked")
ensureServiceStaysRunning()
super.onTaskRemoved(rootIntent)
}
private fun ensureServiceStaysRunning() {
val restartAlarmInterval = 60 * 1000
val resetAlarmTimer = 30 * 1000L
// From this broadcast I am restarting the service
val restartIntent = Intent(this, ServiceRestartBroadcast::class.java)
restartIntent.action = "RestartedViaAlarm"
restartIntent.flags = Intent.FLAG_RECEIVER_FOREGROUND
val alarmMgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val restartServiceHandler = @SuppressLint("HandlerLeak")
object : Handler() {
override fun handleMessage(msg: Message) {
val pendingIntent = PendingIntent.getBroadcast(applicationContext, 87, restartIntent, PendingIntent.FLAG_CANCEL_CURRENT)
val timer = System.currentTimeMillis() + restartAlarmInterval
val sdkInt = Build.VERSION.SDK_INT
if (sdkInt < Build.VERSION_CODES.KITKAT)
alarmMgr.set(AlarmManager.RTC_WAKEUP, timer, pendingIntent)
else if (Build.VERSION_CODES.KITKAT <= sdkInt && sdkInt < Build.VERSION_CODES.M)
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, timer, pendingIntent)
else if (sdkInt >= Build.VERSION_CODES.M) {
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timer, pendingIntent)
}
sendEmptyMessageDelayed(0, resetAlarmTimer)
stopSelf()
}
}
restartServiceHandler.sendEmptyMessageDelayed(0, 0)
}
}
Пожалуйста, поделитесь своим предложением, если вы столкнулись с подобным типом проблемы и вам удалось найти решение для этого.