Search code examples
androidservicesharedpreferencesalarmmanager

Stopping a service at specified time


I'm trying to get this service to stop based on a saved sharedPreferences stop time. As you can see below, mTime is the start time (in milliseconds) to run the pendingIntent from AlarmManager. This code works and always starts my service at the provided start time and listens for an incoming call. The issue is that I don't know where to use the stop time (in milliseconds) to trigger the service to stop/cancel the pending intent.

For instance, say I started the service at 11pm (mTime) but wanted it to stop at 7am (mTime2). It would be ideal if the AlarmManager.set method had a stop time parameter.

Service:

//set alarm to trigger service
public static void setServiceAlarm(Context context, boolean isOn){
    //get shared Prefs time
    Long mTime = SaveSchedulePrefs.getSchedule(context);

    Intent i = new Intent(context, RingerService.class);
    PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
    AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

    if(isOn){
        alarmManager.set(AlarmManager.RTC_WAKEUP, mTime, pi);   //change current time to shared prefs
    } else {
        alarmManager.cancel(pi);
        pi.cancel();
    }
}

Starting the service (this always works based on mTime in the alarmManager.set method):

//register listener
@Override
public int onStartCommand(Intent intent, int flags, int startId){
    mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    return START_STICKY;
}

 @Override
   public void onCreate(){
     mContext = (Context)this;
       mTelephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

       mPhoneStateListener = new PhoneStateListener(){
           // state change 
           @Override
           public void onCallStateChanged(int state, String incomingNumber){
             //set ringer stuff
               myRingerManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
               int ringerMode = myRingerManager.getRingerMode();
               if (state == 1){ 
                   try{
                       Log.d(TAG, " number from incoming call: " + incomingNumber);
                       ...etc...

Solution

  • You could simply add an action to the pendingIntent. for example "my.action.start" or "my.action.stop"

    then in the service onStartCommand check the intent.getAction()

    //Note check for null on the getAction() I'm just typing in code example.
    
    boolean isStart = (intent.getAction().equals("my.action.start")) ? true : false;
    
       if (isStart) {
            startForeground(R.id.action_record, getNotification());
            return Service.START_STICKY;
        } else {
            stopForeground(true);
            return Service.START_NOT_STICKY;
        }