Reputation: 1615
I'm trying to develop simple android application which monitors specified url using http client and once defined condition is met it should perform notification actions.
I have one activity which starts separate thread and put reference to it via static value. (When activity is recreated I'm chechking reference for not null to determinate if child thread was already started). In this child thread I have while loop which gets json data from url and parse it.
I've noticed weird behavour (maybe because I'm android dev newbie). Once application is in foreground it works quite fast, when android device goes into sleep mode it doesn't perform requests to often. (maybe some energy safe policy?). What's the most weird is that once I connected phone to computer via usb cable to works fast (even when application is in background and phone has black screen).
Is there any relationship to activating /disactivating applications based on connected charger? I can't debug it because once I connected cable it works fine, and I can't debug without being connected to computer.
Upvotes: 0
Views: 1028
Reputation: 4178
The matter probably is that phone goes to sleep mode when it stops almost all activity and slows down CPU. It is used to save battery. Timers on Handler.postDelayed()
for example won't work properly (not called on time).
There's special concept for this matter - for activities that needs to be performed in sleep mode, you need to use AlarmManager, see Scheduling Repeating Alarms
The matter is that your app needs to register with AlarmManager, and then it will receive scheduled events when phone wakes up from sleep mode. Your app needs to get lock with PowerManager to perform activities (in your case it's downloading JSON from network), which you do not want to be interrupted with sleep mode while you're executing them. Consider this example:
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
/**
* This method is called when we are waking up by AlarmManager
*/
@Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "pulse app");
//Acquire the lock
wl.acquire();
//You can do the processing here.
//Release the lock
wl.release();
}
/**
* Register our app with AlarmManager to start receiving intents from AlarmManager
*/
public static void setAlarm(Context context)
{
int interval = 10; // delay in secs
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval*1000 , pi);
}
/**
* Unregister the app with AlarmManager, call this to stop receiving intents from AlarmManager
*/
public static void cancelAlarm(Context context)
{
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
This code needs android.permission.WAKE_LOCK
permission in Manifest file.
Another post about AlarmManager usage: Android: How to use AlarmManager
And this: prevent mobile from going into sleep mode when app is running
Article at the first link says that it's preferable to use Sync Adapters for such purpose, but I haven't used them myself.
Upvotes: 1