I've written an application with a foreground service.
The service notification must be updated precisely at 6 pm every day.
I've tried to achieve this functionality with AlarmManager but most of the time it is not working.
Would WorkManager solve this problem (if it is, please explain how I should use it in this case) or is there a way to do this?
WorkManager is the sure bet for your use case. According to the documentation:
WorkManager is the recommended solution for persistent work. Work is persistent when it remains scheduled through app restarts and system reboots.
More specifically, you would need to schedule a Deferrable work, which is a task that starts at a later time and can run periodically.
Related
I have an app where I use a foreground service to start a number N of threads that sleep most of the time and sometimes wake up to do some measurements.
I used foreground services because I need that these measurements must be done at specific and exact time without background limitations introduced by Android 8.0.
This seems to work and from documentation seems that there are no problem, but I read also about JobScheduler.
There is an advantage to use Jobs to schedule work at specific accurate time or my solution can be used without problems.
First a fact
In JobScheduler, the System execute your Job(Task) in application's JobService
and the JobService class also extend the same Service class that we use to define Foreground Service. So by using the both, we can execute code in background
Now the main difference is, Foreground Service is always running(by showing notification to user) and consuming the battery and memory of the user even, if your threads are sleeping and no code is executing.
As it's running always you can do whatever you want precisely at any moment of time. maybe it's good for your app's point of view but it's bad for user. your app draining the battery unnecessarily and consuming the RAM.
To address this problem we got JobScheduler. you can Schedule a job to be executed based on some criteria. Your app will only wake when the criteria is met, but it's not precise.it depends on many factors like doze mode etc.
you can look more about that here
The conclusion is
If your task is not needed to be execute at exact time then you should use JobScheduler (recently WorkManager is better as it use JobScheduler internally and more advance) to save your user's battery
and according official document
WorkManager is intended for tasks that are deferrable—that is, not
required to run immediately—and required to run reliably even if the
app exits or the device restarts.
For your use case, you will be better off using a WorkManager which according to the android documentation, uses JobScheduler on API 23+ and a combination of BroadcastManager and AlarmManager on API 14 - 22.
With a WorkManager your jobs will run reliably even if your app exits or the device restarts.
https://developer.android.com/topic/libraries/architecture/workmanager
My Android application helps users to follow their daily plan by sending notifications at a specific time. This task is easy to solve with JobScheduler. It seems easy, light and up to date solution.
What I'm struggling with is how to plan all notifications every day. I need to run code that checks user daily plan and schedules notification every day at midnight silently. And so far I found 2 approaches
Use JobService. It can be re-scheduled with
public final void jobFinished(JobParameters params, boolean needsReschedule)
but I think it's a bad solution because
I'll need to treat finished job as failed, although it's successful
Schedule time will increase linearly/exponentially and that is not acceptable for me.
Another approach is to use AlarmManager, but it also has a couple of drawbacks
According to documentation
Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted.
And this is not acceptable, as my users can miss something important.
I've read that it kills battery pretty quickly. Is that true?
Other solutions that I've found in documentation doesn't looks like what I need.
(https://developer.android.com/topic/performance/scheduling.html)
Any ideas how run scheduled task on a daily basis that will be light and resilient to reboot?
Using JobService is fine. You do not need to reschedule your job. Just create new job(s) as needed.
I have my own issues with scheduling alarms too. To have things worse, starting with Android 6 there's Doze mode which delays alarms execution.
Please take a look at: https://developer.android.com/training/monitoring-device-state/doze-standby.html
For alarms, you can have a boot complete listener and reschedule the alarms on a restart. If you don't need network connectivity during alarm firing, take a look at Adapting your app to Doze from the above link.
I want my application to trigger an event at a given time. At the moment I'm using AlarmManager. But this will be lost if the users phone is restarted, or the user uses a task killer or ends the application with the android task manager.
So what is the best way to do this. Should I just use an alarm and have it repeatedly set in a service so when it is deleted it come right back?
You can use awake alarm service on boot completed so that all the task will be re scheduled after reboot. You can store alarm id and details in database.
Might be overkill for what you need, but check out CommonWare's WakefulIntentService:
https://github.com/commonsguy/cwac-wakeful
Even if you don't want to fire up an entire IntentService when your alarm is triggered, his code should give you some idea of how you can persist your alarms across device reboots.
I'm implementing an background process that will update information my app uses.
I only want this process to update say once a day, if the process gets data newer than what it had before I want to present the user with a notification, exactly like twitter/gmail does.
I want the update process to run automatically, even when the main app is not open.
Is a Service the best way to go? I've been reading quite a bit about this, I figured a service running all the time for something that is only going to do work once a day seems a little overkill.
However I notice google run service for friendlocation and google+ services continuously on my nexus.
I've look into starting my service via the AlarmManager so its only started when required.
Some posts also suggest using the Handler class, I don't think this will work.
Just looking for the best practice here.
I figured a service running all the time for something that is only going to do work once a day seems a little overkill.
Absolutely.
I've look into starting my service via the AlarmManager so its only started when required.
This is the correct answer.
If you only want your code to be invoked if the device is on, implement an IntentService, do your work in its onHandleIntent(), and have AlarmManager start up the service on your desired schedule.
If you want your code to force the phone to wake up, you can do that, but you will need to use a _WAKEUP-style alarm, and you will probably want to look at my WakefulIntentService, designed to handle this pattern.
I have a service that will monitor location changes daily. What I know so far that to start a service at boot, I have to follow the linked tutorial. This way I can get the service started at boot, but to save battery I need it only between 9am-9pm.
Question is pretty simple, so I will repeat:
How can I ensure a service is started at 9am and stopped 9pm every day?
Use AlarmManager to set two alarms, each with a PendingIntent that will call startService() on your service, but with distinct action strings ('start', 'stop'). When onStart() of your service detects the 'stop' action Intent, it arranges for an orderly shutdown (e.g., stopSelf()).
This will fail if the user applies a task manager to you in Android 2.1 or earlier, since the technique they tend to use will wipe out your alarms (in addition to killing the service). In that case, the user is presumably voting for your service to not run, so you should try to accommodate the user's wishes.
CommonsWare is right. This is the best way.
You are writing an application and you had better not to change anything out of the application. If you want to add a system service(on boot started service), you need to modify the BSP and add your service to systemserver.java. It's not recommended.CommonsWare's suggestion can do this work.
As you said about the activity, you can start the activicy when you receive the boot broadcast. Then do what your want.....