1

I have a widget that, when pressed, sends a broadcast that starts a CountDownTimer that updates my widget, and at the end plays an alarm. This works beautifully in the emulator.

On my phone, however, it's a different story. My phone is so resource constrained that my process is killed regularly, which, of course, means that the CountDownTimer no longer updates my widget.

It seems to be that the only way to reliably do stuff in the future is to use the AlarmManager, as this sets a system-level alarm. However, the documentation states, and I agree, that you're not supposed to use it for ticks. However, since anything else you're likely to use has the possibility of being shut down arbitrarily, they're not really giving us much choice.

My question is: is there a way to ensure that a CountDownTimer keeps ticking and finally calls onFinish(), or do I have to simply drop it and switch to AlarmManager, and "misuse" it? Any other options of guaranteeing that the thing ticks and finishes are also welcome.

I should add that I can't rely on the OS calling onUpdate(), both because it will do so no faster than every 30 minutes, and also because most of the time the widget just does nothing. It's only when it is clicked that it ticks down every second for a handful of minutes.

Markus Jevring
  • 832
  • 1
  • 11
  • 17

3 Answers3

0

To add to the accepted answer: from what I remember, the BroadcastReceiver only lives as long as it takes to process the broadcast.

So launching a timer or something from within the BroadcastReceiver will not work (as stated).

This is why it is recommended to use the BroadcastReceiver to launch a Service that will do the timing. Sure, the service can still be killed, but not as early as the BroadcastReceiver.

Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
0

I think this is a solution.. Create a dummy service..

public class DummyService extends Service{


@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}
 @Override
    public void onCreate() {
        super.onCreate();

    }
    @Override
    public void onDestroy() {

        super.onDestroy();

    }
}

and start it from your activity using countdowntimer like this.. in oncreate of the activity

Intent intent = new Intent(this,  DummyService.class);
startService(intent);

and also dont forget to declare this service in your manifest like this..

<service android:name=".DummyService" >
</service>

hope this helps..

5hssba
  • 8,079
  • 2
  • 33
  • 35
  • Services can still be killed, though. Furthermore, the thing that has the CountDownTimer isn't an activity, it's a BroadcastReceiver, but perhaps that doesn't matter. We'd basically be using the service as an anchor. I know what would happen, though. The customers would still complain that occasionally the countdown wouldn't work... – Markus Jevring Mar 29 '12 at 12:10
  • Actually, a service combined with this might be the ticket: http://stackoverflow.com/questions/3856767/android-keeping-a-background-service-alive-preventing-process-death – Markus Jevring Mar 29 '12 at 12:22
  • It has the advantage of showing a "running" notification in the notification bar. – Markus Jevring Mar 29 '12 at 12:22
0

What I ended up doing was moving from a BroadcastReceiver to a Service. Not just using a dummy service, but having a real service embody what the BroadcastReceiver did previously.

As this won't guarantee that my timers won't get killed, if requested, android will automatically try to restart your service after it's been killed. In this event, I plan to have some code that will restore the running state from disk and continue.

Markus Jevring
  • 832
  • 1
  • 11
  • 17