Search code examples
androidandroid-servicealarmmanagerandroid-pendingintentandroid-alarms

Android - Stopping a periodic service properly


I would like to know if this is the proper way for stopping my periodically called service or not. I have a static boolean variable isServiceStopped in my MainActivity where I can start or stop the ongoing service by clicking on a button. As you see I reschedule my service in the onDestroy() method with AlarmManager, so if I called stopService() in my MainActvity it would just destroy the service but reschedule it again so there would not be any effect. This is why I am using a flag, a static boolean variable that I can set in my MainActivity: if I click the button to stop the service I set this flag true and the service will not be rescheduled again as it will not run in the onDestroy() method.

This is working, but I personally believe that this is just a bad workaround since if I close the app how would the system find the static variable if only the service is running? So what is the proper way doing this? Should I put the reschedule part in the onStartCommand()?

Thanks!

public class AsyService extends Service {

        @Override
        public IBinder onBind(Intent i) {       
            return null;
        }

        @Override
        public void onCreate() {
            super.onCreate();               
        }

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

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
            return START_NOT_STICKY; 
        }


        @Override
        public void onDestroy() {  
            //Right now I have a static variable defined in MainActivity to set the boolean isServiceStopped 
            if (!MainActivity.isServiceStopped){
                AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
                alarm.set(
                    AlarmManager.RTC_WAKEUP,
                    System.currentTimeMillis() + (1000 * 15),
                    PendingIntent.getService(this, 0, new Intent(this, AsyService.class), 0)
                );
            }

        }

    }

MainAcvitiy:

btn2.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, new Intent(MainActivity.this, AsyService.class), PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
            alarm.cancel(pendingIntent);

        }
    });

Solution

  • The correct approach would be to recreate the original pending intent, cancel it, and remove the service from the Alarm Manager. I dont know why you would want to terminate the service from within itself.

    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.cancel(pendingIntent);