I have an application which is for searching colleges, and is running a background service to listen the server for updates, new messages, califications, etc. But in the newest versions of Android (10 and above) the service finish when the user close the app (in the foreground and background).
The question is: what Kind of service or worker (or something) can I implement to listen the server for real time notifications despite the app being closed?
What I tried: service, intent service, workmanager. This solutions finishes when the app is kill. And also foreground service (actually i'm doing this) that works well but has to show fixed icon to notify the user the service is working, and when the app have to show a new notificacion for other reason it won't change (it's like the foreground would have a exclusive priority).
What I don't want: do 'tricks' like send broadcast to another class and restart the service or trigger alarm manager. This things not work and if maybe works cant get so far.
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 have a question about BroadcastReceivers. I have an app that needs to receive constantly the ACTION_TIME_TICK intent to refresh the clock widgets. I implemented a foreground service which contains a BroadcastReceiver that listens to that action. But on android oreo the only way to start a service is starting it as foreground service which implies to show a persistent notification to the user which notify that the app is working in background.
I don't want to show to the user that notification. I tried to implement BroadcastReceiver inside the Application class. But this is not working proprely. Somethimes the BroadcastReceiver doesn't work and somethimes works well. Even when it works well, if the app is removed from the recent tasks, the BroadcastReceiver stops to work. Is there a way to use a BroadcastReceiver that works indefinitely without the use of a service?
Is there a way to use a BroadcastReceiver that works indefinitely without the use of a service?
In the case of ACTION_TIME_TICK: No, since you cannot use a manifest-declared BroadcastReceiver.
Since you're not willing to use a foreground service, you may want to look into START_STICKY. In this situation, that's the only way to maximize your Service's run-time: Allow the system to re-start it, capriciously, after it's been stopped for lack of resources. Of course, this means your clock could stop updating for arbitrarily long periods of time.
Note that your problem is not limited to Oreo (Oreo does not require you to be a foreground service, but it does impose certain limits on what you're allowed to do if you're NOT in the foreground). Even on earlier OSs, if you're not foreground, the system considers you a prime candidate for elimination.
I'm developing a player app.
For this reason, it uses a foreground service to handle the playback.
Until recently the service was bound to my activities.
This is not the case anymore.
Since then, some specific devices (mostly Pixel 1/2/3) have been killing my app 1 minute after the screen has been turned off
The service is a foreground service not bound to anything.
Why would the device kill it?
As soon as the app is excluded from the device-optimized apps list the issue is solved
I'm not providing code, because I'm just trying to understand if this situation makes sense and if so what should I do to prevent this
BTW the app is using a receiver to act on Screen_ON/OFF messages. That's how I can see in the logs that the player service onDestroy() method gets killed exactly 1 minute after the screen has been turned off
what should I do to prevent this?
The key point here to keep the service alive is as said in official documentation :
While an app is in the foreground, it can create and run both
foreground and background services freely.
so, we can conclude that keeping the work in foreground and visible to the user has very minimal chances of being killed. And to do so we need to know that how android gets the idea that this process is in foreground ?
Here are the criteria's at which a process is said to be in foreground:
It has a visible activity, whether the activity is started or
paused.
It has a foreground service.
Another foreground app is connected to the app, either by binding to
one of its services or by making use of one of its content
providers. For example, the app is in the foreground if another app
binds to its:
-IME Wallpaper service
-Notification listener
-Voice or text service
If none of those conditions is true, the app is considered to be in
the background.
If none of the above criteria is fulfilled by your app process then thats the reason of your service being killed.
You can read more on this topic here :
Foreground service being killed by Android
I am developing a chat application in android . and need to keep service running
even after exit from application .
I am usin
return START_STICKY;
in onStartCommand() of my service .
but because of limitation of services in android oreo , service will destroyed after seconds when exit from application.
So far users lost new messages notifications.
I can not use Fcm beacause of local networking and no access to internet.
And I can not use ForegroundService . (because Of Employer's request to not showing any notification) .
When I checked running service in android mobile setting , there are some
apps that their service not killing like Es file explorer , Zapya , ...
How they keep their service running without foreground service .
And What should i do .
Show in blow image , some apps services are running without any notification .
Based on the documentation:
The system distinguishes between foreground and background apps. An
app is considered to be in the foreground if any of the following is
true:
It has a visible activity, whether the activity is started or paused.
It has a foreground service.
Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content
providers.
Reason Es FileExplorer can do could be (its just my opinion) following:
Es FileExplorer (is quite cheeky when it comes to taking advantage of some loop holes) have several content providers but one provider, FileProveders which is some how manages to have com.android.providers.settings connected to it. I guess this connection makes it foreground. They virtually have all the possible intent-filter registered for almost all the scheme. Anything you try to share or access, could trigger them some or the other way which keeps its process in use (you can just click on the details and you will find LocalCService of app running).
But for your app:
If you can't use FCM, ForegroundService and can't have visibility to user, then only option is to perform task periodically. You can use WorkManager. The only limitation is minimum duration for scheduling is 15 minutes. Refer to my answer for scheduling work with WorkManager and WorkManager vs Service for usage of WorkManager.
I am writing an app that connects to a Bluetooth device, continuously receives data from it, and stores in local db. Certain data received requires system alert to pop up. There is a main activity which just displays the status of connection and data received. It all works just fine so far, including the popups.
Since the app requires to be run in background I have implemented a "bluetooth connection" service that manages the BT connectivity, and displays ongoing notification in order to avoid being killed. For coding clarity reasons I would like separate background service to collect all data, and log it (instead of having BT service do all the work). I also prefer loose coupling between my app components, so am using GreenRobot's event bus for all IPC. As a result my BT connection service is completely unaware of any data collection/logging code - it just dispatches a message to event bus and I'd like to keep it that way.
Now I'd like to have my data collection/logging code to be run as another background service. Is there a way to ensure it runs as long as BT connection service is running? And without displaying yet another ongoing notification or tightly coupling the code between two services?
You could let your class extend service so in this case you dont have to make a notification for it. Basically it keep running in the background without the need of displaying notification on the status bar. Make sure before you exit your app to stopservice() otherwise it will keep running until the device restarted or in somehow the user force stop your app from application manager inside of the settings.