user2808671
user2808671

Reputation: 271

AlarmManager stops working after a few days

I have a service which should be run for example every 1 minute. I used a broadcast receiver and AlarmManager to make this work. And also I call PowerManger.aquire() to make sure cpu doesn't sleep before the service starts. For first 2 or 3 days the app runs okay but after that the service doesn't get started. Sounds alarmManager doesn't start it. Any Idea why?

public class MyReceiver extends BroadcastReceiver {
    PowerManager pawerManager;
    public static PowerManager.WakeLock wakeLock=null;
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
         pawerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         wakeLock = pawerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
         wakeLock.acquire();
         Intent serviceIntent=new Intent(context,MyService.class);
         context.startService(serviceIntent);
    }
}

And The Service:

public class MyService extends Service {
    void releaseTheLock(){
        if (MyReceiver.wakeLock != null){
            MyReceiver.wakeLock.release();
            MyReceiver.wakeLock=null;
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub      
        return null;
    }
    @Override
    public void onCreate() {
        // TODO Auto-generated method stub      
        super.onCreate();       
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        final Context serviceContext=this;      
        new Thread(new Runnable() {         
            @Override
            public void run() {
                // TODO Auto-generated method stub      
                    /*
                       Do something
                    */
                    //Now set the timer
                    long currntTime = System.currentTimeMillis();
                    AlarmManager mgr=(AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
                    Intent i= new Intent(serviceContext, MyReceiver.class);
                    PendingIntent pi=PendingIntent.getBroadcast(serviceContext, 0, i, 0);                       
                    mgr.set(AlarmManager.RTC_WAKEUP, currntTime + 60000 , pi);                      
                    stopSelf();
                    releaseTheLock();
                    return;                 

            }
        }).start();
    return START_STICKY;
    }   
}

And here's the receiver registration in manifest:

<receiver android:name=".TimeReceiver"></receiver>

Upvotes: 2

Views: 3242

Answers (2)

Larry Schiefer
Larry Schiefer

Reputation: 15775

I suspect you're running into a race condition where the Service object (Context) is being cleaned up and destroyed, but is being used as the Context for your PendingIntent. Here are a couple of options:

  1. Change your creation of PendingIntent to use the application context. This context is the the one in which your PendingIntent is sent. So if you use a transient context, like the Service object itself, it may no longer be valid.

  2. Revise this to not use the BroadcastReceiver at all. You can create a PendingIntent for your Service via the PendingIntent.getService() method. Again, use your application context here rather than the Service object itself.

Upvotes: 3

Ariel Carbonaro
Ariel Carbonaro

Reputation: 1539

Have you tried with setRepeating?

alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60, alarmIntent);

Upvotes: 1

Related Questions