Keep my IntentService alive when phone is off - android

My IntentService checks the user's location. I need to keep it alive while the phone is turned off. In this Service I have an infinite while loop. The OS will shut it down after 8 minutes.
What other ways can I do this instead of the AlarmManager?

IntentService is supposed to be executed once. When job is done, it terminates. You may try using ordinary Service and do all work on background thread. But, system can stop this service anyway if it is low on resources. To prevent that, you can use .setForeground() method in Service and Service will not be stopped by system. But, there will be icon in notification tray.

Related

Does an empty foreground service keep an android app alive?

I'm working on an app that keeps communicating with a device by Bluetooth(ble) when it's in both foreground mode and background mode.
I know I should implement ble jobs in a foreground service in Android, but the app is written in flutter and all codes are in dart.
It seems that for now even though there isn't a foreground service, the app keeps alive in background mode.
But I want it to be alive as long as possible.
So I'm thinking about making an empty foreground service...
Will an empty foreground service make an app has some priority in background mode?
And is it ok to do so?
Thanks.
The system can terminate an application in the background at any point. In practice if there is no need for its resources, it runs several minutes maybe more.
When using a foreground service, at some point only the service will run, so there is no real use of "empty service". Closing the application manually will leave only the service running.
Yes, an "empty" Foreground Service will usually prevent the app process from being killed automatically by the system, unless the device is critically low on memory.
How the code in the service class itself looks like does not matter. The important thing is that when a Foreground Service is running in the app process, the whole process will be prevented from being killed. This means that you can have Dart threads in the same process that won't be killed. Activities belonging to the same process that are in the background can still be "destroyed" though, i.e. the onDestroy callback can be called.
Since BLE connections in Android uses the Binder mechanism which are not tied to any of the standard Components (Service, Broadcast Receiver, Activity, ...) that otherwise control how the app process stays alive, having an "empty" Foreground Service is actually a common way to keep BLE connections alive.

IntentService + startForeground vs JobIntentService

Since Android Oreo background execution limits, the docs recommend to refactor IntentServices to JobIntentService.
https://developer.android.com/about/versions/oreo/background
JobIntentService runs immediately as an IntentService below Oreo, but schedules a Job on Oreo+
https://developer.android.com/reference/android/support/v4/app/JobIntentService
In what cases would it make sense to run a normal IntentService as a foreground Service with a persistent notification, and when is a JobIntentService better?
One downside I can see in JobIntentService is that it doesn't start immediately.
Foreground service is not affected by Doze, but you still have to use wake locks, if you need your task to be continued when the screen is off.
The JobIntentService (which uses the JobScheduler) manages wake locks for you, but you have less control when the job will be started.
I would use the foreground IntentService (or Service) for high priority tasks (e.g. downloading a database) that should run immediatelly and that should not be paused / killed by system.
I would use the JobIntentService in conjunction with AlarmManager to schedule low priority tasks like refreshing the widget's data periodically.
If you want to make long running operation something like Music Player use Foreground Service with notification. because JobIntentService has time execution limit like JobScheduler. ( 10 minutes)
If you think that user don't need to know about your work you can use JobIntentService without notification.
You don't need to worry about Doze mode if user is actively using your app.
There are some cases for Doze mode, according to https://www.bignerdranch.com/blog/diving-into-doze-mode-for-developers/
Light-Doze starts to kick in shortly after both the screen is off and
the device is not charging, waiting only a couple minutes before
applying the restrictions just to make sure the user has stopped using
their phone
For example, user turned screen off while you are computing something. Your task is finished and you want to run background service. In that case your JobIntentService can be deffered, because device can be in doze mode.
However, if you want immediately perform background operation use ForegrounService with WakeLock, because ForegroundService is not working when the screen is off.

Android - Send data to the server in every 5 minutes

I have some data in my SQLite database table. When my app starts, I want to send that data to the server every 5 minutes.
When the app is closed, it should stop.
What is the best approach for this?
Should I use Service or IntentService?
Should I use AlarmManager, Handler or any other thing?
I'm aware of my application speed. I don't want to make it slow. What is the effective approach?
If you are only transmitting when the app is in foreground, you can do it with a Handler.
You start the handler in onResume() and cancel it in onPause().
And perform the transmision with an AsyncTask or in a separate thread.
If you need to stransmit in background, you can use a service instead and schedule it with the AlarmManager.
And then start the service from the app's Activity.
I am not sure how IntentService would be used for this.
As you just want to run your process while the app is foreground, then TimerTask or Handler with conjunction to Message or Runable is good. It won't bother much your app's performance. If you ask about the better one from these two I'll say it's Handler. Check the details here in this answer:
https://stackoverflow.com/a/3975337/4128371
But if you want a really good performance then I'll suggest to go with AlarmManager. Otherwise Handler is a good option.
Alarm manager is not precise, an alarm schedule for 5 minutes may be that when the device is sleeping it will be fired at twice or triple the time.
If you want accuracy the device does not have to fall in sleep. ( I know that will shorten battery duration)
If you want to prevent the device to go to sleep you need to launch a foreground Service with a non dismissable Notification. That's the Service has to call startForeground()
While the device is awake both Alarmamanager and Handler + Runnable will be accurate ... I prefer the Handler.

Android long time running service

I am working on an Android project and I need the app to work even when the device is locked.
The idea is to open the app that will start the (Intent)Service, the service processes the data all the time. The device can be locked/put away and after some time when the app is opened the service is manually stopped. The service should be running all the time in the background.
I have found information online, but I am not sure what to use and in which way..
I have found that the IntentService can be used. Also the service should run in a new thread. I need to process the data from gps all the time, should I use WakefulBroadcastReceiver?
Thank you.
IntentService is not necessarily what you want to use. It will automatically spawn a new thread just to handle an incoming Intent. Once all incoming Intents have been handled it will stop the Service. To have a long running Service, you would need to derive from Service and when it is started return START_STICKY from the onStartCommand() method, plus spawn your own thread to handle your background work.
If you need to monitor GPS, you'll have to manage that along with keeping the device awake using a WakeLock. Note that in Marshmallow, this gets more complicated because of the new Doze mode where even wakelocks are ignored.
Also, note that the way Android is architected there is still a chance that your application running the background Service may be killed. Android uses a unique process management technique based on memory pressure and user perceived priority to determine how long a process should stick around. I recommend reading up on the Service lifecycle in the documentation.
In android their is no fool proof way to ensure that your service runs forever because the LMK(low memory killer) when the system needs resources (based on a certain memory threshold) , kills the service then if it can restarts it. If you handle the restart properly the service will continue to run.
Services that are given foreground priority are significantly less likely to be killed off, so this might be your best bet. However their will be a notification of your service running the in the background on the menu bar up top. Foreground Service

Service lifecycle in Android

I have a service in my Android application that needs to continue listening for location updates after the user has exited the application (the implications of this on battery life are a separate matter).
I'm not sure that I have correctly understood the lifecycle of a service in Android, outlined on this page:
http://developer.android.com/reference/android/app/Service.html
I believe if it returns START_STICKY in the onStart() method then the service will continue to run after the main application has quit regardless of whether or not the service is running in its own process. If the service is running in the same process as the rest of the app and I have understood correctly, the main app's process is kept alive after the app exits, just to run that service. When the app starts again, it will run in the same process as the service, which is still running. If the system gets low on memory, Android may decide to kill this service.
Secondly, I believe it is OK to run the location listener listening for GPS updates in the same process and indeed same thread as the rest of the application and it will not block when waiting for updates from the GPS.
Have I understood correctly?
You have understood correctly.
If the system gets low on memory, Android may decide to kill this service.
If you want it to be persistent you can create persisitent service (but it needs to be a system app / service).
Please use AlarmManager and an IntentService, so your service does not need to be in memory except when it is doing meaningful work. This also means Android is rather unlikely to kill your service while you are in memory, and users are unlikely to kill your service because they think you are wasting memory.
For your location Listener:
Use the Location Listener implemented in a service.
Start listening the GPS when the service starts and remove the GPS listener when the service stops.
Start this service when you wants to listen to GPS(every 10 minutes for example).
This is cleaner than having a service you try to continuously run and checking for Location changes.
Secondly, I believe it is OK to run the location listener listening for GPS updates in the same process and indeed same thread as the rest of the application and it will not block when waiting for updates from the GPS.
You do not need to setup a AsyncTask or background thread for this. Also understood correctly.
The actual life cycle of Service is described here by image. You run whatever service in android the life cycle if always follow like this.

Categories

Resources