How to implement application idle timeout in android application? - android

Is there a way to implement timeout feature in the following scenarios?
A web application with html pages and native screens.
1.When the application is in the background for 5 min -> destroy the application.
2.When the application is in the foreground but not receiving any user interaction for 5 min ->destroy the application.

I think you can use this.
ApplicationConstants.TIMEOUT_IN_MS will be 300000 //5 min
private void timeout() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
System.exit(0);//close aplication
}
}, ApplicationConstants.TIMEOUT_IN_MS);
}
#Override
protected void onPause() {
super.onPause();
timeout();
}
Cheers,

Regarding background state:
There is no need to kill the app's process manually by default. The Android OS does this by itself if there is a need to free up resources for the other applications.
See this guide for a reference.
Though if you need to perform some background work during this "idle time", you may start a Service to perform those operations and then stop it from code.
Regarding foreground state:
I think the best approach to use here is to send Messages to a Handler of the Main thread of your application, since you do not know if the user will interact with the UI again after they leave. When the user comes back to the UI, you may clear the message queue, using Handler's removeMessages method.
I do not recommend you to finish the process with System.exit(0) in Android.

Related

Android Service that constantly updates Activity

I have built an app for running. It runs an Activity with a timer shown in the user interface, a gps listener that collects coordinates and a lot of other things (the activity does a lot of work).
Now the request of my client is to move all the activity logic in a Service. In this way, when you start a running session, the Service would start and the notification (very simple, just with a static text) would appear. The activity should keep track of the work made in the Service (timer should go on, speed should be shown, ecc...). Tapping on the notification should bring up the activity. If the activity is closed or crashes the Service should keep going on and when you tap on the notification a new Activity should be brought up without the user noticing any difference (the timer should keep showing the right time, the average speed should comprehend the speeds relevated before the activity crash, ecc...).
I know there are a lot of ways to do that.
What I am asking is: what is the best way? Are there examples of such behavior from where to start? What are the common errors I should avoid? Are there best practices to follow?
Thank you
I developed an app with similar service behaviour. It also requires a service which collects data and some activities for showing the data.
For these kind of applications you want to keep the service alive until the user stopps it manualy but it is still possible for android that it kills the service if the device is low on memory.
For the service - activity interaction you need to bind to a service. A good documentation is available here: http://developer.android.com/guide/components/bound-services.html
Be sure to return START_STICKY in the onStartCommand function of the service. This will make sure the intent will be null when the service was restored by the system and tell android that you start and stop your service explicit.
When binding to the service from the activity you need to check if the service is ready (was not restored by the system). This can be done by adding a "ready" field inside the service that is false by default and is set to true if the onStartCommand intent is not null. Therefore you can react properly to a restored service and start the app from the beginning.
To keep the service alive with a high priority you need to call startForeground inside the service. This also requires to show a notification so the users knows a service is running in the background.
Inside service you can use local broadcastmanager.
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
broadcaster = LocalBroadcastManager.getInstance(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000);
return START_STICKY;
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo(); //do watever you want to push
handler.postDelayed(this, 1000); // 10 seconds
}
};

Android - manually stoppable Service in a separate thread

I'm writing an app that plays an audio file and I want it to continue doing so while minimized. I've done this, but I want the audio playback to be on a separate thread, because according to the Android developer website, CPU-heavy services work better on a separate thread.
First I tried using IntentService (this was the perfect solution). However, for some stupid reason, the service destroys itself once the code executed - which is immediately after it starts playing the file. I couldn't prevent this.
Then I created a Thread that runs the Service. However, I don't know how to make the Thread stop the service when needed - the best thing I could do is this:
serviceThread = new Thread() {
public void run() {
while (true) {
if (playAudio) {
startService(new Intent(getApplicationContext(),
MusicService.class));
playAudio = false;
}
if (stopAudio) {
stopService(new Intent(getApplicationContext(),
MusicService.class));
stopAudio = false;
}
}
}
};
Evidently, after that I set startService to true to start the service and I set stopService to true to stop it. However, I believe the Thread has to keep doing the check all the time, thus doing a lot of useless work all the time. I'm not even sure why is the app working, isn't it doing like million checks every second?
How can I properly do this?
Assuming you can't block the thread that the service runs in, you can add a java.lang.Thread.Sleep at the end of the loop if you're worried about doing too much work.
You might also want to read up thread scheduling and time slicing to understand why your app is still working (but probably using a lot more CPU than necessary).

Android How to implement services for time delayed actions?

I implemented some app, that waits about some time before action. User can go to preferences and define time to wait. My problem is now that if I press home button I canĀ“t start any other app, because my app take all resources. I have an motorloa milestone and my code is (part of source code of waiting service) :
public void run() {
while(currentTime>waitingTime)
{ currentTime = System.currentTimeMillis();
Thread.sleep(1000);
}
//do Action
}
It is an simple thread, but it seems to be very ineffective. I would be very thanks-full for any help.
you can always use Handler to schedule a Message. But your application needs to be in running state to get a call in Handler's callback mathod(handleMessage(message)). Another option is to go for AlarmManger.
Use AlarmManager to schedule a PendingIntent to be invoked at your designated time.

How to make periodic rest requests from Activity?

One of my activity periodically updates nearby friends, which location is obtained from rest service
Currently I use postDelay:
private Runnable updateNearbyFriendsTask = new Runnable() {
#Override
public void run() {
list = api.getNearby(.....)
handler.postDelayed(this, UPDATE_RATE);
}
};
The problem is that postDelayed executed on UI thread, so this runnable task block ui with poor internet connection.
What is the right way to make periodic background rest requests from activity? I don't want to create service for that, because this rest method is used only in this activity.
EDIT
Currently switched to using ScheduledExecutor
this.scheduledExecutor.scheduleWithFixedDelay(new UpdateNearbyFriendsTask(), 0, UPDATE_RATE, TimeUnit.MILLISECONDS);
private class UpdateNearbyFriendsTask implements Runnable() {
#Override
public void run() {
list = api.getNearby(.....)
runOnUiThread(.....)
}
};
I don't see what the problem is with creating a Service, even if it is only used for this activity.
That being said, have a look at the TimerTask. It seems to do what you want.
How about BroadCast receiver using Alarm manager.. http://developer.android.com/reference/android/app/AlarmManager.html
Since its a long running and on going task, would you want to write a Service or an Intent service which does the background job for you.
You can just ping the service whenever your time ticks and let the service do the network activity, freeing up the UI thread for something else. you can always query the service to know the status, or the service itself can respond back to your UI thread.
For ticking the timer, you can use the alarm manager, or perhaps something else (I am not good at any :P )

How to arrange long (time consuming) actions on Android?

For instance, we are in SomeActivity and the activity has a button that invokes moving files from one dir to another (let's call it job).
On BlackBerry I would:
push a non-cancellable popup (Dialog screen) saying "Please wait..."
start a thread that fulfills the job
on thread completion close the popup
This approach 99.99% can guarantee that we stay on the same screen after the task is over, user just sees the popup and waits for job completion. Device rotation or whatever does not break the desired workflow.
On Android things change. I know there's the AsyncTask that is probably provided to solve my case. There's even a good example of how it should be used. But since there's no guarantee of how long an Activity instance will live the AsyncTask should be cancelled on onSaveInstanceState (and restarted on onRestoreInstanceState). This means using AsyncTask there's no guarantee we are able to fully fulfill the job once started. In some cases as sending an http post request for creating a user I would not want to get in "user already exists for this login" trouble on reruning the AsyncTask. This is possible since the AsyncTask can be interrupted while the request is already sent (and the server actually is doing its job - creating a new user), but the AsyncTask is canceled before we got the response.
Is there any solution on Android to get the BB-like behaviour stated above?
But since there's no guarantee of how
long an Activity instance will live
the AsyncTask should be cancelled on
onSaveInstanceState (and restarted on
onRestoreInstanceState).
Or have it be managed by a Service.
If your Activity wants to stay on the screen, you can simply start a Thread like this:
final File fromFile = ...;
final File toFile = ...;
new Thread() {
#Override
public void run() {
// do something with fromFile, toFile
}
}.start();
That way the GUI-Thread is ready to do other thinks like displaying a
android.app.ProgressDialog
Also, consider making the Dialog uncancellable with
ProgressDialog.setCancelable(false);
That way the user can only leave via the HOME-Key, which you get notified of when
Activity.onPause()
is called. Futhermore you might want to look into Wakelocks, to stop the Screen from turning black and your application pushed in the background where it might be killed. You'd do this in the Thread:
PowerManager pm = (PowerManager) ivContext.getSystemService(Context.POWER_SERVICE);
Wakelock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "MyApp");
wakeLock.acquire();
// ... copy stuff ...
wakeLock.release();
Of course you'd have to release the wakeLock, too, when the user leaves via the HOME-Key.
Finally if you want to call GUI-Elements from your background-thread, this will only work if the Thread is part of the GUI-Event-Loop, like the normal Thread is you are running in, when getting called with on...-Methods. To achieve this your background-thread will have to callback to the GUI-Thread via a Handler. Like this:
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
Log.v(TAG, "Got Message "+msg.what); // prints: Got Message 77
// ... do GUI actions ...
}
};
// ... in Thread ...
int lvInfo = 77;
mHandler.sendEmptyMessage(lvInfo);
You can even put objects in the message like so:
Message txtMsg = Message.obtain();
textMsg.obj = "Hello World";
mHandler.sendMessage(lvTextMsg);
In May 2010 Google issued a new IO session called Developing Android REST client applications which explains how to achieve exactly what I asked for.
It turned out the question is rather complicated, so there is no easy and quick solution. The solution requires deep knowledge of Android platform/API. This is the price caused by the flexibility of the app process/Activity lifecycles.
I feel some oddity on why this info was not presented from the very first version of Android. Looks like Google knew how to write 100% bugless apps and for some marketing reason did not share the approach. Just imagine how many buggy apps was written by May 2010.
Anyway I'm glad now I have smth we call best practice approach.

Categories

Resources