In my App i am using the TimerTask with an Interval of 1s. If the App is in the background, I show the current Time in the NotificationBar. So every second in the onTick() Method I update the silent Notification. But with Android 10 it stops updating after few minutes. All Notifications are blocked, also the other channels.
Is there a new permission or another way to show the Time in the NotificationBar?
your application might be killed in background so that's why it stops showing the updates.
Try using workmanager for your app to run continuously below is the links
workmanager
Key features:
Backwards compatible up to API 14
Uses JobScheduler on devices with API 23+
Uses a combination of BroadcastReceiver + AlarmManager on devices
with API 14-22
Add work constraints like network availability or charging status
Schedule asynchronous one-off or periodic tasks
Monitor and manage scheduled tasks
Chain tasks together
Ensures task execution, even if the app or device restarts
Adheres to power-saving features like Doze mode
Related
i'm making an app for events and users can set alerts to the events they want. I use the AlarmManager for this, and the problem is on Android 9(Pie), that it seems blocking alarms and the notifications is not showing anymore.
For Android <= 8 there aren't problems.
Any tip/solution here?
Thanks
Alarms do not fire when the device is idle in Doze mode. Any scheduled alarms will be deferred until the device exits Doze. If you need to ensure that your work completes even when the device is idle there are several options available. You can use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() to guarantee that the alarms will execute. Another option is to use the new Schedule tasks with WorkManager, which is built to perform background work either once or periodically. For more information, see Schedule tasks with Schedule tasks with WorkManager.
Ref: Android Developer.
I have been reading lately about how background jobs are done in Android (using Service, AlarmManager, JobScheduler, etc) and learned that these background task can go indefinitely even the app has already closed or device has screened off. I understand that the only they stop if they stop themselves or other components stop them.
Questions:
If I have a background job or an alarm that goes every 1 hour. Does it really runs forever until a component stop them? Is there an instance that the system will stop them?
What if I have periodic job or alarm that goes every 1 hour. Will they stop if I uninstall the app that started them? Cos I never read this part in any documentation.
Is there a way to check any running or pending background jobs/alarms in my device?
The explanation that is given about background tasks in your question only applies to Background Services, that to only in Android API Levels below 26.
Google recommends using JobScheduler or Foreground Service to do some work in background even when app is not in foreground.
Coming to you questions
No, If your using JobScheduler or Alarm manager the system will trigger your job to do your work depending on device idleness and conditions mentioned by you but the system can anytime come and stop your work in between when the conditions are no longer met.
If your are using JobScheduler it will inform you when system wants to stop by force so that you can handle it properly and reschedule if needed
When the App is uninstalled every job or alarm that is scheduled or in-Progress will be destroyed.
Yes, JobScheduler does provide a function 'getAllPendingJobs'
Note :
For works that should be scheduled or completed even when app is closed then try avoiding the use of Background Services or Alarm Managers.
JobScheduler is much more better replacement.
If you want to do some simple background work when the app is in foreground then try using HandlerThreads or AsyncTasks
My app has a background service running that gets users current location and update it to a server every five minutes. To run this location update process continuously, I use alarm manager to set its next execution time from the service itself. However, when I install the app in my Nokia 6 running Android 8.1 it works for some time and if I keep the phone idle for some time, my service will get killed with the next alarms by the application also being cleared from system alarm manager. My guess was that the idle time makes the phone enter doze mode. However, I don't understand why the alarm managers got cleared. To my understanding, the doze mode should open up maintenance windows periodically to execute any pending tasks.
To mitigate this issue, I tried to apply a JobScheduler service on top of AlarmManager, which runs every 15 minutes. Purpose of this jobscheduler was to re-start the service which has the alarmmanager in it, so even if it gets killed and the alarm is cleared, jobscheduler would re-up the service.
After I tested this patch and keeping it for some time to go into idle mode, it resulted in getting both JobScheduler Service and Service which has the alarm in it killed with the scheduled jobs and alarms getting cleared from the system.
It is said in the Android documentation that we can use JobScheduler to mitigate its background execution limitations. And to test this out I forced killed the two services when I tested the app, but the already scheduled job did not get cleared, and it made the service with the alarm run again successfully. I don't understand the reason for this behavior, although the Evernote guys give an explanation that could match this scenario in here Android Job by Evernote
Any ideas for this abnormal behavior?
Test Environment Details
Device : Nokia 6 (TA-1021)
OS : Android 8.1.0
You would not be able to run background services long running in Oreo as there are behaviour changes, now Oreo to optimise system memory, battery etc, it kills background service, to solve your issue you should use foreground service.
Have a look at Background execution limits https://developer.android.com/about/versions/oreo/android-8.0-changes
A suggestion from me, if you can use FCM then go for it, becasue apps like WeChat, Facebook uses it, to deliver notifications and they don't face any problem...
Hope this helps in understanding the issue....
In Doze more, the alarms do not get reset, but get deferred to a later time. You have two mainstream options here:
Use either setAndAllowWhileIdle() or setExactAndAllowWhileIdle(). However, these too can fire at the maximum frequency of 1 time per 9 minutes. So you'll have to decrease the frequency at which you get location in your app.
Use a foreground service by way of showing a foreground notification. Everyone does that (apps like Uber, Google Maps etc). That way, your service won't get killed, and be treated as though you have an app open.
I'm currently facing the same issue and doing the same workaraound like you do. That is, setting the Jobscheduler to a periodic job to launch my Foreground Service every 15 min in case it is getting killed for whatever reasons like a killed task. This works like a charm on pre Oreo Versions.
For Oreo the only solution I am awared of at the moment is, to allow the app to autostart in the settings. Under installed apps that is. Then it should work like pre Oreo again.
What Ive heard but not tested yet, is to set the setPersisted(true) option in the Job Scheduler.
Let me know if that helps
I assumed currently DOZE mode not allowed to background service so you need to find a way that DOZE mode will not affect on your app.To solve your issue you should use foreground service. or make some battery setting. Any way my better option is you should go with Firebase Cloud Messaging
I am using AlarmManager in our app to set alarms that are set at specific date and time. Now recently few users of our app are complaining that these alarms are not popping up. Also, in Android O guidelines, it is mentioned that app should not run any background service and instead should switch to Firebase JobDispatcher. I have following 2 questions
In our app, we do not do any background task except to show notification to user at the specified time and date. Even in this case, should we switch to Firebase Jobdispatcher?
In case we do need to switch to JobDispatcher, how can the Job be set to run at exactly specific date and time?
Because you're not doing any background tasks like network requests or long running CPU operations, I think you should continue using Alarm Manager.
Now recently few users of our app are complaining that these alarms are not popping up.
This is because when doze mode triggers, it is not guaranteed that your alarms will be triggered(see this).
What you can do is use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() methods from AlarmManager class as per your requirement for API level >= 23.
According to the documentation these are appropriate for notification purposes.
setAndAllowWhileIdle() documentation:
Like set(int, long, PendingIntent), but this alarm will be allowed to
execute even when the system is in low-power idle modes. This type of
alarm must only be used for situations where it is actually required
that the alarm go off while in idle -- a reasonable example would be
for a calendar notification that should make a sound so the user is
aware of it. When the alarm is dispatched, the app will also be added
to the system's temporary whitelist for approximately 10 seconds to
allow that application to acquire further wake locks in which to
complete its work.
In my Android app I need to do some work every time the user plugs their device. For this purpose right now I use a BroadcastReceiver, which starts my IntentService to do the work when the user plugs the device and stops it when the device becomes unplugged.
Right now I'm thinking of using JobScheduler for Android 5.0+, but what I'm seeing is that with JobScheduler, I would have to schedule my job within the app, by calling
JobScheduler.schedule(JobInfo);
But this is a problem to me, because I want my job to run every time the user connects their device to the charger, even without the user having to open my app.
For this reason, I think one way would be to schedule it the first time the user opens the app, and then always force reschedule, since I cannot trust on the user opening my app every day (which, due to the nature of my app, certainly won't happen).
So, should I stick with BroadcastReceiver or use JobScheduler for Android 5.0+?
And in the case of using JobScheduler, should I schedule my job only once and then always return true in order to force rescheduling?
Thank you.
So, should I stick with BroadcastReceiver or use JobScheduler for Android 5.0+?
Use JobScheduler, this can improve your app’s performance, along with aspects of system health such as battery life. Also, JobScheduler persists through device reboots and supports batch scheduling by which the android system can combine pending jobs thus reducing battery usage. Moreover, you can do distinguish between android versions thus using JobScheduler on Lollipop and up, and AlarmManager on older versions.
And in the case of using JobScheduler, should I schedule my job only once and then always return true in order to force rescheduling?
Now, there are 2 ways to do this :
As you guessed, scheduling your job only once and always returning true in jobFinished() - this should do the trick.
Upon completing a job (originally scheduled by you by calling JobScheduler.schedule(JobInfo)), you schedule another job by calling the same. This will schedule consequent jobs once each job is about to be completed.
Jobscheduler runs in the background and persists through reboots so you should be fine.