Best strategy to implement this behavior in Android app? - android

In my Android app, I have some data that needs to be synced daily but also needs to be updated every hour when a user is inside the app.
I have already implemented a service that gets called from an alarm for the daily update. Im having a problem with developing a strategy to do the hourly sync. I could use an hourly alarm too and fire the same intent, but since your app can be killed at any time, there would be no way to cancel it (and since they use the same Intent, doing a cancel would cancel ALL alarms including my daily sync, so that's probably not good).
The other option is to use a Timer that's set when inside the app, and have that fire my Intent when inside the app. Im assuming all Timers get cancelled when an app is killed right? But my app consists of several activities and I want the timer to work across all activities, how do I do that? I dont want to duplicate code - we're already using a subclass for Activity and ListActivity.

I have some data that needs to be
synced daily but also needs to be
updated every hour when a user is
inside the app.
The solution seems easy: drop the second requirement. Few apps are used continuously for hours on end, since people tend to use their Android phones for other things (e.g., phones), so your update-hourly-if-used-all-the-time code will probably never run.
I could use an hourly alarm too and
fire the same intent, but since your
app can be killed at any time, there
would be no way to cancel it
FWIW, your app will not be killed while it is on-screen. And, while it is not on-screen, you don't want the updates going hourly.
Im assuming all Timers get cancelled
when an app is killed right?
Apps generally are not "killed". We expect you to clean up after yourself when your activities are called with onDestroy(). If you set up the Timer with a daemon thread, you will need to terminate that thread.
But my app consists of several
activities and I want the timer to
work across all activities, how do I
do that?
Bind to your service from each of your activities. If it is started by your alarm Intent, have it do normal update processing. If it is started due to a binding request, just have it make sure its hourly Timer is running. When it is called with onDestroy() (e.g., after all activities have unbound), have it stop the Timer.

You might be able to have a Timer run in a background service (which get killed less than activities) but there is still no guarantee that Android won't kill your service either. And running something like this is the background might use a lot of battery.
What about doing the hourly sync in a background thread that get's created in onResume? And just save the last time the user did the sync, and if it has been > an hour just do the sync. Because I don't think there is any reason to eagerly sync data that the user is never going to see.

Related

What should I use specifically for running a light background task?

I am in the process of making an app that will be triggered by a system broadcast and would take time input from the user, after which the app should just run a timer and do a task after the timer is over. My questions are as follows:
Do I need to use a background task for this, or is this possible to be achieved without it, because I need the timer to run even if the app is closed in the app drawer.
If I do need to use a background task, what should I use, an AsyncTask, a Service or a JobScheduler?
I understand that a BroadcastReceiver will listen to any system broadcasts, and since I have registered in the Manifest, the app will start on any such system broadcasts. However, as soon as the app is started due to the system change, I need it to popup a dialog box which takes input in the form of time (HH:MM:SS), and after that a timer begins which runs for that amount of time and as soon as the timer stops, another task is done.
I also don't want the task to be a one-up, meaning that I want it to be to done every time the system receives the system change broadcast.
For what you want to do, you basically need three things.
A BroadcastReceiver for receiving a system broadcast. This component is essential. Also, you don't have to worry about it being a one-up thing. A registered BroadcastReceiver will continue to run it's onReceive() method until the BroadcastReceiver is unregistered by you or the system, or if you intentionally place code in to block it from activating.
An Activity to display the Dialog. Technically, a BroadcastReceiver can also display a Dialog, but BroadcastReceivers are meant for short and quick tasks, so it's not a good place for this. An Activity where you show a DialogFragment is the better option because compared to a Service, an Activity is really the component meant to display a UI.
An AlarmManager for counting down the time. Rather than creating a Service yourself to handle the timer, you should use the AlarmManager with exact time to help you respond to the amount of time that passed. You can also use a JobScheduler as an alternative to AlarmManager, since both are meant for executing code at a later time. Which one you choose depends on the task you want to do later on. Personally, you should also consider the new WorkManager, which is the better option in my opinion. Depending on what you need to do, it will internally use a JobScheduler or AlarmManager, which helps get rid of the deciding process for you.

Long running background task, Android

I am parsing all text messages from the device and extracting words from them. For doing this I first used Service, but the issue with it was that it made application slower or sometimes I got notification that Application is taking longer to run.
Alternative to this I used IntentService. But problem with intent service is that whenever I stopped the application, I couldn't see my service running anymore. Alongside I also have to use Alarm Manager to schedule the things.
I am planning to use SyncAdapter for doing both of the things, but I don't think it would be a good option to use it. It would be really helpful if there is a better possible for doing this.
Background task might take upto 5-10 minutes for completion and I am planning to run it in every 12 hours. Though I won't be parsing old messages again. So it won't take longer after first time. The task should not end even when application is closed.
Basically IntentService is apt for background tasks which are not tied to the application lifecycle.
But problem with intent service is that whenever I stopped the
application, I couldn't see my service running anymore.
You can send updates to UI from intent service by using:
LocalBroadcastManager: how to use LocalBroadcastManager?
Handler: How to Collect info from IntentService and Update Android UI
Also you might want to see this video: The Zen of IntentService. (Android Performance Patterns)
EDIT:
Forget about using IntentService, it stops as the app stops because it runs on the same process as the app.
Since you want your service to work as a job every 12 hours, you could use a 'Scheduled Service'.
You can use JobScheduler or Firebase JobDispatcher API

How do I create a android service that runs continuosly?

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.

android: Timer for Quiz app

I'm involved in developing a Quiz app for android. Each collection of questions should be answered within a specified period of time. This period of time can be measured using an android CountDownTimer.
However, CountDownTimer pauses when the app is no longer in focus.
What should I do if I want to timer to continue running, even if the app is closed? (If the app is reopened and the timer has expired, the app should display a suitable message).
Use the lifecycle of your Activity
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Override OnPause() method (called when activity loose focus)
stop the timer
store the current time
Override OnResume() method (called when activity returns in foreground)
compute the elapsed delay
if the timer has expired : display message
else restart the countdown timer with remaining seconds
Just listing down possible ways it could be implemented (best one first):
user2553764' s answer of just saving & calculating timer value based on system. (Best suited, it is simple & requires no background services or threads).
Using handler, see How to set a timer in android. (Official documentation suggests it use for timed operations, though seem overkill for your use case).
Using a Service (bindservice), Implementing a Count down timer using Service in the background. (But services can go out of memory, in that case might have to use it with 1st approach).
AlarmManager, dunno if it should be below binded service but it can be used none the less.
How to run a method every X seconds, suggests use AlarmManager for >10min intervals else Handlers. (Also mentioned in android documentation as you stated above).
You want to create an Alarm using AlarmManager. They run regardless of what activity is on screen, and even runs when the phone is asleep.

Android Timer Alternative

I'm looking for some timer alternative, since timer dies with app, is limited, and every timer launches own thread.
Sometimes I need to launch about 20-30 timers.
I need to set some event, in time, and when it comes display app screen. Is it possible?
This may or may not be possible depending upon your definition of "dies with app".
You can use AlarmManager to schedule PendingIntents to be invoked at specific times in the future. Those PendingIntents can launch activities. This will work if your app "dies" from ordinary causes.
However:
If the user force-closes your app via Settings, your alarms are unscheduled, and there is nothing you can do to stop this (nor do you have any alternative to AlarmManager that somehow survives this)
Please allow the user to determine whether or not you display an activity or raise a Notification at these times, as users may not necessarily appreciate having their game, navigation, video, or phone call interrupted by your activity.
You should use AlarmManager.
As CommonsWare says that there are some limitation of it, but that is ok, if an user force closes your application it means he doesn't want to use your application (any more or due to sort of memory)....
And I have a solution (but may be not the best), because you can not listen if user force closes your app, so one way is that you can re schedule your event on each start of your application. I know this is not a good solution but ..... we have no any other way yet
Here is a good example.

Categories

Resources