Closed TheValkDokk closed 2 months ago
This plugin already registers an alarm to restart the service if it terminates abnormally.
The below permission are required to allow the OS to better restart service in doze mode.
// AndroidManifest.xml
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
// dart
FlutterForegroundTask.requestIgnoreBatteryOptimization();
but, this method also seems to have limitations. If anyone has a better idea, please let me know...
This is how i do it on my other Kotlin app, works even on Xiaomi Hyper OS which aggressively kill the app as soon as user remove it from the recent apps.
Restarter
class Restarter : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
context?.let {
startSerialService(it)
}
}
private fun startSerialService(context: Context) {
val newIntent = Intent(context, SerialService::class.java)
newIntent.action = SerialService.Action.START.toString()
context.startService(newIntent)
}
}
Both Service and Main Intent have this:
override fun onDestroy() {
super.onDestroy()
val broadcastIntent = Intent()
broadcastIntent.action = Constant.RESTART_SERVICE
broadcastIntent.setClass(this, Restarter::class.java)
this.sendBroadcast(broadcastIntent)
}
Service onStartCommand
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
notification = getNotification("Serial Service is running")
startForeground(1, notification.build())
Timber.d("onStartCommand")
when (intent?.action) {
Action.START.toString() -> start()
Action.STOP.toString() -> stop{}
}
return START_STICKY
}
I think keeping the BroadcastReceiver alive is important for the service to start again when terminated
The RestartReceiver.setRestartAlarm
function also requests service restart in a similar way as above.
The difference is that AlarmManager is used to wake up the device from the doze state and restart the service.
Calling sendBroadcast directly is blocked in doze mode. It is explained in the official documentation, and this limitation has also been confirmed on actual devices.
I see it easier to restart the service using setAlarmClock
and setExactAndAllowWhileIdle
functions of AlarmManager, but this requires the SCHEDULE_EXACT_ALARM
permission and the user to allow it by going to the Alarms & Reminders settings page.
Unless the app provides a exact alarm service, the SCHEDULE_EXACT_ALARM
permission may make it difficult to distribute the app due to Google policy.
This might be one way too, so I'm planning to add an option.
Thank for the info about sendBroadcast in doze mode, my app does in fact categorize somewhat as an alarm app with health tracking features so this could work
Sorry for the late reply, i will check it out
Thank you for your hard work
In my app, the service is really importance as it's handles bluetooth data and sync to server, but it's have 25% change of getting kill by the OS (Android, Samsung phones), i tested with 4 phone and 1 out of 4 foreground service will get terminated. So i wonder is there any other way to avoid this? Could you add a flag that can be use for force restart when service get terminated.
i tried something like this before using onDestroy to send to BroadcastReceiver and start the service again.
I know this will make the app hard to be approve by Playstore but an option flag would help alot.
My app requirement is like this:
I seek guidance, Thanks in advance