IntentService unique and coupled to notification - android

My app is running an IntentService to download data in the background. While doing so, it sends Notifications to update the user about the progress.
The problem is, if the BatterySafe mode gets started, the IntentService gets killed, the Notifications stay there though (for example saying 30%).
Is there a way, to couple the lifecycle of the notification to the lifecycle of the service?
A second problem is, that I only want one instance of the IntentService. Is it possible, to achieve this?
In some Apps, for example the Avast AntiVirus, the background task seems connected to the notification, indicating that this background task is running. If this is a standard solution, it seems to solve my problem, so it would be great, if you could tell me the name.

Related

WorkManager or Foreground Service?

Once the user gets into an activity, I need to send a value to the Web Service and, once s/he exits the activity, I need to send another value to the server. It needs to happen at that exactly moment.
Android Developers guide says I should use Foreground Services for background tasks which need to be executed immediately, and WorkManager for deferable tasks. However, I do not need to update anything on the UI nor a notification (as they are mandatory in Foreground services) after the task is done...
What should I use?
UPDATE:
As said in the comment
OnDestroy is not even guarenteed to be called on process death and moreover. The correct approach is a foreground service that shows some generic "syncing with server" message until it's done

Content Observer Detecting Change after Activity Destroyed, Should I use Service?

I have a content observer detecting onChange successfully when the application is running in the foreground. I want to kill my application (swipe it away) but still have this content observer be able to detect onChange. I have tried many many things, but need help achieving the dream scenario.
Start a foreground service (which forces a permanent notification), and registers the content observer in the foreground service. This method "works" but I really hate that permanent notification. My app currently work this way and I get complaints about the notification, thus my motivation to find a better method.
Start a background service, keep it sticky. This does not work, because in newer version of Android, even sticky services gets killed after your main app gets killed
Start a background service, on its onDestroy() method, send broadcast to restart the service. Basically read this guide. This doesn't really work either, my service restarts a couple of times, then I get errors which basically says I am trying to restart my service too many times.
Start a background service, which starts a thread that runs forever. In the thread, do the content observer. I haven't tested this method yet, but it seem really bad because It will probably create orphaned threads, just seems really bad coding practice. Has anything tried something similar?
So basically the issue newer and newer Android is recycling services in almost all situations. How do I keep a background service running forever, because I need a content observer to run forever and listen to changes.
Other posts which i have read are this, this, this, this

Android - how to overcome the 10 second limit when receiving broadcasts from IntentService?

I would like to know, I have an Activity that receives broadcasts from an IntentService that needs to save data and then export it to a CSV file. However, this can take longer than 10 seconds, and I know there are certain problems with starting AsyncTasks and Threads using BroadcastReceivers that they might get killed after 10 seconds. I would like to know, how would I overcome this?
EDIT: Note that what I am actually doing is saving data from sensors, calculating data, and then exporting. Apparently when the app is in the stopped state when receiving the save command from the other app, the app gets stuck in the calculation state. The save and export use AsyncTasks, but the calculation uses a Thread where I send a message back to the Activity using a Handler. Does anyone know how I would get around this? I used PendingResult in the saving portion, but now it gets stuck in the calculation portion.
Have it launch a Service to do the work, rather than doing it in the Receiver itself.
Here are different approaches to save data in background.
Android background processing
It really depends upon your requirements. If exporting to csv can tolerate a little bit delay, use WorkManager as its battery friendly and automatically uses best approach depending upon API level.
Use foreground service, if you want immediate high priority background execution and you also wanna notify user because foreground services are visible to users via a non-dismissible notification in the notification tray. For example, WhatsApp attachment uploading.
If it is not a very long running background task and you don't expect user to close the app during this, you can use any background execution approach like ASyncTask, Rxjava, kotlin Coroutines.
background execution evolution. A very interesting article to read and compare these different approaches.
I figured out a solution. As suggested, I used a foreground service, however, there was an issue with my callback to my activity in my background thread that was started by the service that the callback interface was null when the app was paused. I was able to fix that.
Thank you for your help.

Can a manifest-registered BroadcastReceiver + Service combo operate when its parent application is closed?

I have been trying to get an Android service to take pictures in the background using the action.USER_PRESENT trigger. Suprisingly enough, it works.
I am confused about the mechanisms involved however. Going to list some points below, please correct where I am wrong.
When an intent filter is registered in the BroadCastRecevier via manifest, it will be triggerred even if the app is closed, correct?
The created service runs its methods on a newly created thread, and will execute until end, no matter what.
What are the mechanistic differences in how the service behaves when the app is open, in the background (or stopped in some devices), or destroyed?
action.USER_PRESENT triggers when the user passes his lockscreen?
In addition, I would invite suggestions to alternative triggers to USER_PRESENT, when my condition is that the service be triggered whenever the user is using his device.
When an intent filter is registered in the BroadCastRecevier via manifest, it will be triggerred even if the app is closed, correct?
Android developers do not use "app is closed", as that is not a specific description. Many things might qualify as "app is closed". In this particular case, your receiver will work even if your process is terminated, which is my guess for what you mean by "app is closed".
The created service runs its methods on a newly created thread, and will execute until end, no matter what.
No.
First, in Java, objects do not run on threads. Methods run on threads.
Second, there is no requirement that any work done by a service "will execute until end".
All a service means is that you are telling the OS that you are doing work that is not tied to the foreground UI, and that will hint to the OS to try to keep your process around a little bit longer. How long "a little bit longer" is depends on Android OS version, system RAM, what the other apps on the device are doing, etc.
What are the mechanistic differences in how the service behaves when the app is open, in the background (or stopped in some devices), or destroyed?
Apps are not "destroyed". An app's process being terminated is the closest thing that I can think of to what you might mean.
Once an app's process is terminated, all running code is gone, including any running service code.
There is no difference in the behavior of the service itself whether the app has foreground UI or not. Having foreground UI means that the app's process is very unlikely to be terminated, assuming that your code does not crash.
action.USER_PRESENT triggers when the user passes his lockscreen?
Yes, IIRC.

how do I make an android service that runs when the application doesn't?

my knowledge of services in any operating system, is that they usually run in the background and perform whatever work they have to do.
but the first time I got familiarized with android services, I got confused.
it appears they only run when the application is working, and that for me, makes them no more then sophisticated threads.
do I have this all wrong? how do I make a service that runs when the application doesn't? (so that I can check for updates and create notifications for the user that will then lead him to the application if he chooses to open them).
does push notifications have anything to do with it?
Edit:
thank you guys for your answers so far.
my problem seems to be the fact that the service is only started officialy when the device is booted up. I do call startService when the app starts, but that doesn't seem to help. the service still dies when the app is turned off (unless it was booted)
also I never call stopService
If you are trying to implement a long running task that is performed in a (background) service, you have to start one or more threads within your service. So the service just gives you the opportunity to have an application context without having to have a user interface ;) you can consider it as a kind of container.
This page give you a nice overview about different thread approaches in Android. As you can see a service has not its own thread.
Anyway, in your case it seems that an AlarmManager is probably the better option. Running services for polling information all the time can be quite CPU and battery consuming (see this post for instance). So try to avoid having threads that run all the time.
If you can push information about updates from a server it's just fine. Check out Googles Cloud Messaging in this case.
Michael who commented on my question first was right in his comment about startService()
so it goes like this:
my receiver is only activated on boot, and uses an AlarmManager to
time the service to certain intervals.
what I did was to bind the activities to the service. if the service
was off and I binded it and unbinded it, then by the time the app was
terminated, there was nothing keeping it alive.
by simply making sure that the service was started properly with
startService if it is not already on, I managed to keep the service
alive at all times
also thanks to Trinimon who gave a very nice explanation on what
services are, and the importance of not overloading the CPU with
excessive polling. (which is kind of a trade off situation)
good luck to all :)

Categories

Resources