I am trying to implement a timer with notification that cannot be swiped away by user. I want to continuously update the timer's time.
I know there are a lot of similar question online. But a lot of them discuss using handler, or a service. All of these won't run when my app is not being used by the user. AlarmManager doesn't work because i want to update every x millisecond.
Thanks.
Use a foreground service
A foreground service performs some operation that is noticeable to the
user. For example, an audio app would use a foreground service to play
an audio track. Foreground services must display a Notification.
Foreground services continue running even when the user isn't
interacting with the app.
There is a limit on how frequently you can update the notifications as well, every MS will cause problems.
Related
Can anyone please explain to me at technical level, why does a music player's service run continuously after the screen is turned off. Why is it never affected by doze mode? I want to create a service along similar lines, but it should perform a particular task every 20 seconds continuously.
I would be glad if anyone can explain this. Thanks in advance.
The music player's service runs as a 'foreground service'.
Foreground services for the most part are unaffected by doze when used in combination with a partial wakelock:
Purpose of WakeLock in modern Android?
If your app needs to create a foreground service while the app is in the background:
ContextCompat.startForegroundService()
Inside the service, promote it to the foreground and post the notification by calling:
startForeground()
From the Android docs:
"A foreground service performs some operation that is noticeable to the user. For example, an audio app would use a foreground service to play an audio track. Foreground services must display a Notification. Foreground services continue running even when the user isn't interacting with the app."
https://developer.android.com/guide/components/services
Typically, a music app will change the foreground service notification from a 'liability' that annoys the user to an asset by displaying an image of the artist, the current track and offer media buttons like play/pause/rewind/forward.
A foreground service should not generally be used to do regularly scheduled work because it will greatly reduce the device's battery life.
Instead, try to use WorkManager, JobScheduler or Firebase Cloud Messaging to wake the device up only when necessary.
Execute frequent tasks using the Work Manager API
But it will not be possible to "poll" or run your code every 20 seconds with these solutions. You really need to find a solution that works with "Doze" instead of fighting against it.
I would love to offer a background notification service(real-time) but can't find a way how to make it work since background services get stopped by system and when I restart them from a receiver I get an error.
I see that other apps have it, but I checked the running services and they don't have any services there. Do you think they do it in some short intervals to check for new notifications ?
Any advice would be helpful.
You have two choices:
1:Foreground Service.
You can keep a service running indefinitely, by promoting your service to a "foreground service". You can only become a foreground service by adding a Notification for the service to the notifications area. Presumably one which allows users to make your service go away. See Service.setForeground.
Poll periodically using WorkManager and AlarmManager
These APIs allow you to schedule periodic work when there is an active internet connection. The basic idea is that you would poll every few minutes to see whether there is stuff to be done.
There are no other options. This is by design. There is no way to lurk in the background constantly without displaying a notification. Android OS developers have put a lot of work into making sure that there is no other way.
In my app I want to show notification on exact time when the app is working in background or even it is closed. I used AlarmManager and service with BroadcastReceiver to show notification. The latest versions of android doesn't allow to run service in background after app closed and foreground service is consuming battery, slowing down the device etc.. I wonder if I could use something else can work even app is closed and show the notifications. I've heard of WorkManager and JobScheduler for that kind of operations but can they do the work even if app is closed?
Foreground services is not consuming more battery and not slowing down device, just notification is shown.
And the answer is basically it is not possible to make continuous background service on new android API's. You only can schedule tasks with tools like WorkManager, JobScheduler and so on.
These days I think WorkManager is the answer because Android team is focused on it this year.
Also even continuous foreground services gets killed after some time.... To avoid that 2 things has to be done:
Native battery optimization for app should be disabled.
Phone manufacturer (another battery optimization) has to be also disabled for specific app.....
I know it is worst user experience, and they throwing away half smart things that phone can do, but life is life :)
I want app to start a timer at certain point and run for four hour and is displayed in UI.
Now problem with using service is that it closes if app is closed. (Same with Handler)
And if I use system time than if someone changes system time, 4 hours extends
So is there a better way to implement such task?
You can make services not close when the activity (visible) is stopped. One way to guarantee it stays alive is to make it a foreground service (will show a notification). But if you don't make it a foreground service it will still last for some time unless your device is running out of battery for example.
In your case, to make it last four hours, perhaps use the foreground service alternative (showing a notification)
Foreground service
Vogella foreground service
AlarmManager should help see page http://developer.android.com/reference/android/app/AlarmManager.html
I would like to notify my users of new content available in the latest version of my android game without using an external service like Push Notifications.
What I would like to do as a first step to achieve this is to just create a standard notification on application update.
This brings me to my question: is it possible to start a service the first time a user launches the game and then just keep it running indefinitely? I want to even keep it running after an update completes. Since it is possible that the code for the service may have changed between versions, would I need to stop the old version of the service manually and start the new version? Is it possible to even do something like this where the event that drives initiation of the service is the completion of an app upate?
My plan is to have this service check some persisted data about the last time the user was notified about new content and based on this I will be able to determine if a notification should be created for them after they update.
It's important that they are not required to go back into the game after update in order for the notification to be created. This is the problem that I am having now. Auto-updates occur and they don't know and hence also don't know that there are new stages, etc, available so they never go back into the game if they were already done with the previously available content.
It seems that games like Family Guy have got this approach working, but I am not sure if they implemented it in this way. Even after I update it, I will still get notifications even if I have not actually executed the app since update.
Services are mostly killed when other process needs the resources. Therefore use
startForground(...)
for running Services indefintly on background.
See here: http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)
What you can do is use the AlarmManager in your service that notifies you at certain time. Start the service, do the task and set again an alarm to notify you. In this way, you'll be able to run your service infinitely at periodic time.
I started redacting this answer on GameDev Stack Exchange before you
deleted the question. Unlike the guy who told you to delete, i thought it was an interesting question even for game dev stack exchange.
What you describe is a bad practice on android. I don't believe any game do that. What's more, android require "service" app to run as ForegroundService (This force you to display you app icon in the notification bar, so that users are always aware of running services) It can also be randomly be killed when the system lacks memory. However it can be implemented nicely using Alarms and AlarmManager.
Services and Notifications :
You can however schedule intents when the app is running, with AlarmManager, this is the good practice. Let's take a simple exemple : Candy Crush.
In Candy Crush, when you lose your last life, every 30 minutes you regain one, and have a limit of 5 lives. You want to notify the user when all his lives are back. How to do that ?
Exemple 1 :
When the user lose his last life or quit the game, schedule an intent with AlarmManager in (5-number_of_life)*30 minutes that will fire a local notification.
Exemple 2 :
Schedule an intent with AlarmManager every 30 minutes to check the number of lives, and fire a notification when the user have 5 lives again.
Using a Boot receiver may also allow you to schedule things as soon as the device boot.
However, users expects to be able to disable this kind of features.
Updates :
If you want your app to notify users when an update is available, you'll need to somehow check on the internet with a request on your server. You may schedule an intent again with alarm manager to check regularly if the update is available. If the user is ingame, you can also check it more regularly.
A lot of "online" games do that, and simply force the user to download the new update from the Play Store, before they can play again.