I want to save some data into a file/db immediately without using a foreground service in the background (as I don't want to draw user's attention), when users leave the relevant Activity.
I was thinking of spawning a background service and if my background service fails to execute it's work due to system pressure, I can enable START_STICKY and check if the intent is null when the service is restarted. Only maybe then turn the service to foreground service or, schedule a job (through WorkManager or AlarmManager, depending on how important the data is for users). However, neither of them is quite what I want. Foreground service will make the notification appear, and managers will schedule the work (not immediate).
Has anyone any idea about how to do that?
Related
I've read that I should call
startForegroundService(intent)
if I want to properly start a service that can run as a foreground service. But how should I think if I want it to start without it being a foreground service but potentially becoming one later on? Some info on how we have it right now:
We have an App which uses a service for many tasks. It performs all of these task when the user interacts with the app in the foreground but depending on if the user has enabled a certain feature we want to keep performing these tasks in the background. So when the app is launched (and obviously is in foreground) we start the service using
startService(intent);
When the app transitions into background we check whether the feature is enabled, and if so, run startForeground(id, notificiation); which effectively adds the non-removable notification out in the OS and the service keeps on running. When the app goes back into foreground we call stopForeground(true). If the feature isn't enabled the service will never be set as a foreground service and we won't try to perform these tasks in the background.
So my question is: Is this sufficient to get the "full foreground service performance"? Or am I losing something by not calling startForegroundService(intent)? My impression is that we actually do have a fully working foreground service but I'm getting confused when I read statements that foreground services must be started using startForegroundService(intent) which we're not doing. If we really need to use startForegroundService(intent), the only solution I can think of would be to initially start a normal instance of the service and when the app enters background we start a new one using startForegroundService(intent). But do we need to do this or is running startForegund(id, notification) on a service started using startService(intent) sufficient to achieve a foreground service?
NOTE: One difference I find is that if the application itself is in background when start the service I then need startForegroundService(intent) for API >= 26. In our case we always start the service when the app is in foreground. I do however recall some instances where I've seen the exception thrown when we try to start the service using startService(intent), somehow the app (very very rarely) still think it's in background (perhaps something from the OS comes up just when app is launched). So if I catch when that happens I could run startForegroundService(intent) to start the service. But is it possible to run stopForeground(true) on that service when the app comes back into foreground? Or is it bound to be a foreground service forever since we started it that way?
Seems like you don't have to call startForegroundService and startService is sufficient:
If your service is started (running through Context#startService(Intent)), then also make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. By default started services are background, meaning that their process won't be given foreground CPU scheduling (unless something else in that process is foreground) and, if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You use startForeground(int, Notification) if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.
From Documentation
I read your question multiple time and I think (hopefully) the answer to your question is :
According to the official document of Android 8.0 Background Execution Limits:
Android 8.0 introduces the new method startForegroundService() to
start a new service in the foreground. After the system has created
the service, the app has five seconds to call the service's
startForeground() method to show the new service's user-visible
notification. If the app does not call startForeground() within the
time limit, the system stops the service and declares the app to be
ANR.
So, make sure you have started ongoing notification by calling startForeground (int id, Notification notification) in the onCreate() method of your service.
Note: Apps targeting API Build.VERSION_CODES.P or later must request the permission Manifest.permission.FOREGROUND_SERVICE in order to use this API.
And there is great medium article posted by Maciej Witowski that help you understand how really new services API works :
https://proandroiddev.com/pitfalls-of-a-foreground-service-lifecycle-59f014c6a125
I Can't understand the differences on android services
I want to have a service run all the time in the background (activity recognition)
When it detect that I RUN -> open GPS -> save curent longitude latitude -> if I stopped to run (WALKING) -> display the log lat on my MainActivity
i want the service run if the user close the app , if the device is closed and re-open , if my service is killed
so I read about:
[Started Service , Intent Service , Bound Service , Intent Bound Service , Job Scheduler , Job Intent Service].......But still i missing something
I understand that with Service start_sticky for API<26 will run forever (if not killed) and with IBinder I can update the UI of my MainActivity; right?
My Many Q are ...:
1. Bound services can run for ever? and update my UI of MainActivity? do i need bound or i can achieve this with service or intent service
2. For oreo I "must" use Job Scheduler -> when killed -> open again with broadcast receiver || work manager || alarm manager ||?
My questions are more for theory Answers not code.
NEED to -> service for "ever" run -> if (something) -> open gps -> save long lat -> show long lat in UI of MainActivity.
To keep a Service running indefinitely in the background, use a foreground service. This will force you to maintain a visible notification/nav bar icon; that's the price Android extracts from you in exchange for keeping your service running for a long time period. Supported on API 5+.
JobScheduler/WorkManager/AlarmManager won't prevent your Service from being killed. They can be used to bring your Service back to life. Also, JobScheduler and WorkManager can get your system out of doze, so you can do useful work. A WakeLock may also be necessary. If the user explicitly terminates your app, JobScheduler jobs will no longer wake it up. I don't know of any good, "Android-approved" way to resuscitate an app in this circumstance. Although, even on Oreo+, you can register to receive these intents, which you can use to regain execution.
You can make any of the Service subclasses you mentioned into a foreground service (by calling startForeground(). The choice of subclass is a matter of convenience, and depends on how you would like to dispatch & schedule your work. Your app could just as easily be implemented with the base-class Service.
START_STICKY doesn't actually prevent a Service from stopping. It's more like a request to the system: "After you kill my app/service, please restart it, if/when you see fit". In my opinion, it is not an effective way of keeping a Service running for a long period of time. If a Service is not in the foreground, and no other application components are in the foreground (e.g., on screen), then Android can kill your app quite quickly. This is more true of later versions of the OS (Oreo+).
Your Service will need to be bound to other components (e.g., Activities) from time to time. You bind to a Service so you can 1.) Make sure it exists and 2.) Carry out communications with it (call functions on it, etc.). So, yes, with IBinder, you can update the UI of your MainActivity.
Binding a Service doesn't make it run forever. If your Activity is bound to the Service, you can be confident that the Service will stick around for as long as the Activity is onscreen. Once it leaves the screen, all bets are off.
In other words, Android is very likely to kill an app/service when it's not in the foreground, and not bound to any components that are in the foreground (onscreen).
A Service can generally open up an Activity at any time it chooses, simply by calling startActivity(). Your Activity can even dismiss the keyguard (in certain circumstances), using FLAG_DISMISS_KEYGUARD.
If you can tolerate less frequent location updates, you may be able to do this without staying in the foreground, but there are limitations.
I need to start a foreground service for my app so that it keeps running and is unlikely to be killed even if the app is in the background. The is a method for this, startForeground.
I also need to communicate with the service, so I gather the easiest option would be to bind to it (I am planning for it to run in the same process to be able to just cast the returned IBinder to my class and just call methods on it). However, nowhere can I find information about bound foreground services.
Reading through the docs and tutorials I found information that one of the flags tobindService is https://developer.android.com/reference/android/content/Context.html#BIND_NOT_FOREGROUND to prevent the service from getting foreground priority.
Does this mean that by default every bound service is also a foreground one, and it needs notifications and the like (the docs never actually mention it so I guess not)?
If my app uses a foreground service, can the app be killed while in the background?
Well, let's talk about services. Service can be started, bound and both of them. So you actually can make startService() and make startForeground() after it, but when you're going to bindService(), you can remove notification and make service not foreground (seems like flag BIND_NOT_FOREGROUND for this situation). Bound service is not foreground by itself (they have priority of component that are bounding to service). As i know to make foreground bound service, you can't just call startForeground() (it will not work, no notification will be added in status bar), so the only way is to make startService() and in onStartCommand() handle action that will do only startForeground().
So by default bound service isn't foreground, you don't need notification. Your app can be killed in any time by the system or by user in app's settings (Force stop), but if you want to let system know that your service is really important for user and app, you make it foreground so system will not touch it until system has enough memory for your process.
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
I am currently writing my first Android application and I keep running into references to background and foreground services. Since I intend on using a service in my application I was hoping to get a clarification between the two and how they are used.
Perhaps this will answer your question:
A started service can use the startForeground API to put the service
in a foreground state, where the system considers it to be something
the user is actively aware of and thus not a candidate for killing
when low on memory. By default services are background, meaning that
if the system needs to kill them to reclaim more memory (such as to
display a large page in a web browser), they can be killed without too
much harm.
More info can be found here
Foreground: The process relies on onPause() and onResume()...i.e you play music player and pressing pause and play
Background: The process which runs without user interaction i.e receiving a message, incoming call, receiving mails, or setting alarms. The method used here is onStart() and onStop().
For example, check it on your phone. Create an alarm at 6:30am. When the system clock reaches 6:30am it fires. In order to kill the alarm service, just go to menu-->settings-->application-->Running service-->click stop service. It stops the alarm service even when your system reaches the time it won't fire.
Foreground Service is used when User is interaction with application and when Service is doing something visible to user. Background Service is used when even user close application (discard from recents) and when Service is doing something not visible to user like downloading data from server, load data from a ContentProvider etc.. And Foreground Service is less likely to be killed by system on low memory.