Reputation: 271
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
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:
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.
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
Reputation: 1539
Have you tried with setRepeating?
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60, alarmIntent);
Upvotes: 1