part-1 persistent foreGround android service that starts by UI, works at sleep mode too, also starts at phone restart

前端 未结 3 711
心在旅途
心在旅途 2020-12-15 10:05

Status:--- I equally accept Karakuri\'s and Sharad Mhaske\'s answer, but since Sharad Mhaske answer after the

3条回答
  •  长情又很酷
    2020-12-15 10:46

    I have made something like this myself but I learned a lot while developing it and discovered it is not completely necesary to have the service running all day draining your battery. what I made is the following:

    Implement a Service that reacts to events. In my particular I wanted to automate my Wifi and mobile data connection. so i react to events like wifi connecting and disconnecting, screen turning on and off, etc. So this service executes what ever needs to be executed responding to this event and then stops, scheduling any further actions with the AlarmManager if so needed.

    now, this events can by timers like you said yourself every 15 minutes it does something and sleeps, that sounds to me that you really dont want the service running 24/7 but just executing something every 15 minutes. that is perfectly achievable with the AlarmManager without keeping your service running forever.

    I recommend implementing this service deriving from commonsware's WakefulIntentService.

    This class already handles the wakeLock for you so that you can exceute code even if phone is asleep. it will simply wakeup execute and go back to sleep.

    Now. About your question regarding the activity starting and stoping the service. you can implement in the button that it starts or cancels the AlarmManager alarm. Also you can use the sharedPreferences to store a simple boolean that tells you if it is enabled or not so the next time your service runs it can read the value and know if it should continue or stop.

    If you implement it as a event-reactive service as i said, your button can even react to broadcast intents so that your activity doesn't even have to call the service directly just broadcast an intent and the service can pick it like other events. use a BroadcastReceiver for this.

    I'll try to give examples but be wary that what you're asking is a lot of code to put it in one place...

    BootReceiver:

    public class BootReceiver extends BroadcastReceiver
    {
      private static final String TAG = BootReceiver.class.getSimpleName();
    
      @Override
      public void onReceive(final Context context, final Intent intent)
      {
        final Intent in = new Intent(context, ActionHandlerService.class);
        in.setAction(Actions.BOOT_RECEIVER_ACTION);  //start the service with a flag telling the event that triggered
        Log.i(TAG, "Boot completed. Starting service.");
        WakedIntentService.sendWakefulWork(context, in);
      }
    }
    

    Service:

    public class ActionHandlerService extends WakedIntentService
    {
      private enum Action
      {
        WIFI_PULSE_ON, WIFI_PULSE_OFF, DATA_PULSE_ON, DATA_PULSE_OFF, SCREEN_ON, SCREEN_OFF, WIFI_CONNECTS, WIFI_DISCONNECTS, WIFI_CONNECT_TIMEOUT, WIFI_RECONNECT_TIMEOUT, START_UP, BOOT_UP
      }
    
      public ActionHandlerService()
      {
        super(ActionHandlerService.class.getName());
      }
    
      @Override
      public void run(final Intent intent)
      {
        mSettings = PreferenceManager.getDefaultSharedPreferences(this);
        mSettingsContainer.enabled = mSettings.getBoolean(getString(R.string.EnabledParameter), false);
        if (intent != null)
        {
          final String action = intent.getAction();
          if (action != null)
          {
            Log.i(TAG, "received action: " + action);
            if (action.compareTo(Constants.Actions.SOME_EVENT) == 0)
            {
              //Do what ever you want
            }
            else
            {
              Log.w(TAG, "Unexpected action received: " + action);
            }
          }
          else
          {
            Log.w(TAG, "Received null action!");
          }
        }
        else
        {
          Log.w(TAG, "Received null intent!");
        }
      }
    }
    

    And your Manifest could go something like this:

    
    
    
        
    
        
        
    
        
    
            
                
                    
                    
                
            
    
            
            
                
                    
                    
                
            
    
        
    
    

提交回复
热议问题