Android - Service, IntentService, JobIntentService - they are stoped if app killed

Viewed 2102

I have read to many same questions here in StackOverflow and in Web but cannot configure something like "never ending service" or running even when app is removed from task (force killed). I am just wondering how services like Viber or WhatsUp working, because when we force killed those application we are still able to receive messages when someone write to us(So service is running still). I know about foreground service , but it is not solution because user don't want to see the notification. So here what i have tried. : This code in running inside services to detect real-time changes, and just wanted for this to stay active in every condition of app : Foreground, Background, Removed etc...

firestoreDb!!.collection("example").document("example").collection("real_time_request")
                    .addSnapshotListener { documentSnapshot: QuerySnapshot?, _: FirebaseFirestoreException? ->

                    }

I am using service like this to get real time data from Firestore Database when something changes in user's collection.

The ways i tries services are :

FirestoreListeners : IntentService("Firestore Listeners")
FirestoreListeners : Service
FirestoreListeners : JobIntentService

Everything above is working fine when app is in foreground or in background, but the services are killed after app is force closed (when removed from task)

I have tried to make this changes in manifest :

android:stopWithTask="false"
android:directBootAware="true"
android:process=":remote"

In application hierarchy :

android:persistent="true"

In IntentService onHandleIntent :

setIntentRedelivery(true)

In service onStartCommand :

return START_STICKY

Tried to to restart service if the system destroy or kill it :

override fun onTaskRemoved(rootIntent: Intent) {
        val restartServiceIntent = Intent(applicationContext, this::class.java)
        restartServiceIntent.setPackage(packageName)
        val restartServicePendingIntent = PendingIntent.getService(applicationContext, 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT)
        val alarmService = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent)
        Log.e("Service Firestore ", "Task Removed")
        super.onTaskRemoved(rootIntent)
    }

But nothing works OK. What is the best solution to achieve this ? So the purpose is for something to be running on background and listening for Firestore Changes(or something else) even after app killed or removed from tasks , like Viber etc... Maybe they are using foreground service without notification icon ? But i don't think that Android allow us to make this kind of foreground service (without notification)

I have read some articles about WorkManager and as Google says :

Note: WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.

But can't figure out how it is exactly work or how to use for my purpose

Thanks

4 Answers

You could use FCM push notification to woke up the device when your app is in not running/foreground.When app receives push notifications, you could start your service to do required task. Again you might not be able to start service when app is in background, for that you might need to run service as foreground service.

WorkManager is now the best solution for doing some work background. Because now Android OS is more restrictive about what it allows to run in the background for a long period of time. From the official documentation... WorkManager chooses an appropriate way to schedule a background task--depending on the device API level and included dependencies, WorkManager might use JobScheduler, Firebase JobDispatcher, or AlarmManager.

Android developer website is a good place to start learning WorkManager https://developer.android.com/topic/libraries/architecture/workmanager/basics.

For a periodic task that will run continuously with a delay in between, You can create a PeriodicWorkRequest and enqueue it on WorkManager instance. https://developer.android.com/topic/libraries/architecture/workmanager/basics#recurring

Another older way is just using AlarmManager. In this way, you don't have to keep running a service in the background all the time. You can set a repeating alarm and when it fires, you can start a service and do what you need.

In Android Doze mode documentation they specify the use of FirebaseJobDispatcher which will work even in Doze mode. but this will work only once in every 15 minutes. You can use WorkManager from Android Architecture components which can appropriately use FirebaseJobDispatcher, AlarmManager and JobScheduler on corresponding supported API levels

Related