AlarmManager stops running

2019-09-08 04:06发布

问题:

I'm writing a program that should run every 10 minutes in the background. The code I have seems to work fine as long as I'm actively using my phone, but after a long period of time, say overnight, the process seems to stop on it's own. When my program is running as it should I can view it under the "cached process" on my device, but then it will stop showing in the list after awhile.

I was reading about WakefulIntentService and was wondering if I need to use that. As I understand it, it will keep your background process running even if the phone sleeps. Not sure what "sleep" means in Android, if it's when you power off, or does the phone go into a "sleep" state if it's not used for awhile.

This is the code I'm using:

Main class:

 public class Main extends ListActivity
 {
      @Override
      public void onCreate(Bundle icicle) 
      {
           AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

           Intent myIntent = new Intent(this, AlarmReceiver.class);
           PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
           alarmManager.cancel(pendingIntent);

           alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, 600000, pendingIntent);
      }
 }

BroadcastReceiver class:

 public class AlarmReceiver extends BroadcastReceiver 
 {
      @Override
      public void onReceive(Context context, Intent intent) 
      { 
           context.startService(new Intent(context, MainService.class));
      }
 }

Service class:

 public class MainService extends Service  
 {  

protected void handleIntent(Intent intent) 
{
    // obtain the wake lock 
    PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); 
    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag"); 
    mWakeLock.acquire(); // check the global background data setting 
    ConnectivityManager cm = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE); 

    if (!cm.getBackgroundDataSetting()) 
    { 
        stopSelf();
        return; 
    }

    new FetchItems().execute();
}
 }

 private class FetchItems extends AsyncTask<Void, Void, Void> 
 {
    protected Void doInBackground(Void... unused) 
    {           
      SomeLongProcess();
      return null;
    }

    @Override 
    protected void onPostExecute(Void result) 
    {   
        stopSelf();
    }
 }

 @Override
 public int onStartCommand(Intent intent, int flags, int startId)
 {
   handleIntent(intent);
   return START_STICKY;
 }

 @Override 
 public void onStart(Intent intent, int startId) { 
   handleIntent(intent); 
 }

@Override
public void onDestroy() 
{
         super.onDestroy(); 

         AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

         Intent myIntent = new Intent(this, AlarmReceiver.class);
         PendingIntent pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
         alarmManager.cancel(pendingIntent);

      mWakeLock.release();
}

AndroidManifest.xml:

<receiver android:name=".AlarmReceiver"> 
    <intent-filter> 
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter> 
</receiver>

回答1:

Does it really have to run every ten minutes even when the device is asleep? If it doesn't, use AlarmManager.ELAPSED_REALTIME and your service will be run when the device is wakes up, saving a lot of battery. As for your question, you can assume that the screen going dark == going to sleep (of course, if other services are holding wakelocks, that is not the case).