I have a Service that shows a toast every 10s, but I'd expect Doze to slow it to every 15 minutes when it's in the background as the app is not whitelisted. Here's my service:
#Override
public void onCreate() {
super.onCreate();
if (mTimer != null)
mTimer = null;
// Create new Timer
mTimer = new Timer();
// Required to Schedule DisplayToastTimerTask for repeated execution with an interval of `2 min`
mTimer.scheduleAtFixedRate(new DisplayToastTimerTask(), TIMER_DELAY, TIMER_INTERVAL);
}
...
private class DisplayToastTimerTask extends TimerTask {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Hello world", Toast.LENGTH_SHORT).show();
}
});
}
}
What I'm getting in the emulator is that the toast is shown every 10s even when I'm at the home screen. Doesn't Doze restrict all non-whitelisted background services/apps to 15 min waking time?
Doze occurs only when the screen is off, and has been for some minimum amount of time. It has nothing to do with just backgrounding.
In addition, Timers or Threads set by the service wouldn't automatically be canceled, as 1)the OS doesn't know about them and 2)There's no way to know if its safe to do so, or if doing so would cause deadlock or other errors. They may be delayed to the Doze allowed rate of execution, but would not be stopped.
Related
We have an app who should process a task every 10 seconds. This should be more or less exact, which means that a difference of 1 or 2 seconds is OK, but not gaps of 20 seconds or more.
This should work regardless if the app is open, in foreground or in background.
We implement this via AlarmManager, but it is not working properly. If the smartphone is not plugged in and it is running in background, there are gaps in the execution.
With Android 4.3., we have gaps (about 30 seconds) from time to time, with Android 5.x we have fewer gaps, but gaps about 5 or 10 minutes long!
I think there must be a way to implement this, an alarm clock is also possible and is exact.
More about the app: It works in a service and a broadcast receiver is implemented. This means the service is restarted if I wipe away the app or restart the handy. This works correctly. The only problem is the 10 second task.
Any hints? How is an alarm clock implemented? Which calls, API?
I tried different ways until now without success.
Thanks
Hans
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
// PerformBackgroundTask this class is the class that extends AsynchTask
performBackgroundTask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 10000); //execute in every 10000 ms
}
You can do it with handler and runnable, which I think is preferred by Android..
public class ActivityMain extends Activity
{
private Handler mainHandler = new Handler();
private Runnable backgroundTask = new Runnable() {
#Override
public void run() {
//do your background task
mainHandler.postDelayed(this, 10000);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainHandler.postDelayed(backgroundTask, 10000);
}
}
Use of "AlarmManager" with "broadcast Receiver" and "service". These 3 component will make your requirement fulfill.
Using Alarm Manager to generate a Broadcast Receiver, and from BroadcastReceiver start a Service where you can put your desired code of logic to get your task done in every 10 Seconds.
I am writing a data logger app and I need to make an http request every 5 minutes exactly. The user is aware of the battery drain and that's ok for me. I am using a foreground service with the appropriate notification for that and I have a handler thread to witch I post runnable tasks every 5 minutes. It seems that when the phone enter DOZE MODE the thread is suspended and no runnables are executed. Is that normal behaviour or I am missing something?
Any help on how to do that will be appreciated.
Service code that starts the thread:
private void startTheForegroundService() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainService.this);
builder.setPriority(Notification.PRIORITY_HIGH);
startForeground(1000, builder.build());
httpThread = new HttpThread("Ping Thread", Thread.NORM_PRIORITY);
httpThread.start();
httpThread.loop();
}
Thread code:
public class HttpThread extends HandlerThread {
public Handler mHandler;
public HttpThread(String name, int priority) {
super(name, priority);
}
public synchronized void waitUntilReady() {
mHandler = new Handler(getLooper(), new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
return false;
}
});
}
public void loop() {
waitUntilReady();
mHandler.post(new Runnable(){
#Override
public void run() {
//code for the http request.
}
});
}
}
Is that normal behaviour
Yes, for the Doze mode in Android 6.0, which triggers when the app has been stationary for an hour or so. The M Developer Preview extends Doze mode, such that it also partially triggers even when the device is moving, though I think your scenario would continue to work in that case.
The user is aware of the battery drain
The user can add you to the battery optimization whitelist (Settings > Apps > (gear icon) > Battery Optimization).
Following is the code snippet which I am using in my project to schedule a task
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
#Override
public void run() {
//Do Something
}
}, interval, interval);
This works fine. I get event after mentioned interval. But this fails to send any event if date is set smaller than current from settings.
Does any one know why this behavior is happening?
Timer fails when you change the system clock because it's based on System.currentTimeMillis(), which is not monotonic.
Timer is not an Android class. It's a Java class that exists in the Android API to support existing non-Android libraries. It's almost always a bad idea to use a Timer in your new Android code. Use a Handler for timed events that occur within the lifetime of your app's activities or services. Handler is based on SystemClock.uptimeMillis(), which is monotonic. Use an Alarm for timed events that should occur even if your app is not running.
Use this code.. this will help you..
Timer t;
seconds = 10;
public void startTimer() {
t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (seconds == 0) {
t.cancel();
seconds = 10;
// DO SOMETHING HERE AFTER 10 SECONDS
Toast.makeText(this,"Time up",Toast.LENGTH_SHORT).show();
}
seconds -= 1;
}
});
}
}, 0, 1000);
}
i build app which give Location update to server in background using service and broadcastreceiver.i put timer(Run every X Minute) which run method of location.it include fatch lattitude,longitude and update to server with API Call.
I have a problem and quastions . there is a list of this.
1.my timer goes sleep when device is in standby mode or sleep mode
2.i have to update location if user last location and current location distance 500m or greater.
3.I want to know how much minute or second tack device for going sleep mode?
4.my timer run perfactly in running devoce mode than why stop or sleep in device sleep mode?
my timertask
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
location();
notifyUser2();
Log.d("timeeeeeeee22222222", "time22222222");
// display toast
}
});
}
//in oncreate
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
Is the currect Way to timer run? if yes than Why it Sleep while device in standby mode or sleep mode?
Help me i searched lots of sites but can't get it.
Thanks in advance
I am currently trying to set up a WiFi Scan in my Android application that scans for WiFi access points every 30 seconds.
I have used Timer and TimerTask to get the scan running correctly at the intervals which I require.
However I want to be able to stop and start the scanning when the user presses a button and I am currently having trouble stopping and then restarting the Timer and TimerTask.
Here is my code
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
public void doWifiScan(){
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
wifiManager.scan(context);
Log.d("TIMER", "Timer set off");
}
});
}};
t.schedule(scanTask, 300, 30000);
}
public void stopScan(){
if(scanTask!=null){
Log.d("TIMER", "timer canceled");
scanTask.cancel();
}
}
So the Timer and Task start fine and the scan happens every 30 seconds however I cant get it to stop, I can stop the Timer but the task still occurs and scanTask.cancel() doesn't seem to work either.
Is there a better way to do this? Or am I missing something in the Timer/TimerTask classes?
You might consider:
Examining the boolean result from calling cancel() on your task, as it should indicate if your request succeeds or fails
Try purge() or cancel() on the Timer instead of the TimerTask
If you do not necessarily need Timer and TimerTask, you can always use postDelayed() (available on Handler and on any View). This will schedule a Runnable to be executed on the UI thread after a delay. To have it recur, simply have it schedule itself again after doing your periodic bit of work. You can then monitor a boolean flag to indicate when this process should end. For example:
private Runnable onEverySecond=new Runnable() {
public void run() {
// do real work here
if (!isPaused) {
someLikelyWidget.postDelayed(onEverySecond, 1000);
}
}
};
using your code, instead of
scanTask.cancel();
the correct way is to cancel your timer (not timerTask):
t.cancel();
The Android documentation says that cancel() Cancels the Timer and all scheduled tasks. If there is a currently running task it is not affected. No more tasks may be scheduled on this Timer. Subsequent calls do nothing. Which explains the issue.