How to stop the service at certain times of the day?

I managed to start the service at a specific time of every day, but I want to do the same thing to stop, but I do not know how to do it.


Here is the code that I use to start the service using AlarmManager.
note: I'm new to android dev, so providing a full code comment will be appreciated.

Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 9); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); PendingIntent pi = PendingIntent.getService(getApplicationContext(), 0, new Intent(getApplicationContext(), Service.class), PendingIntent.FLAG_NO_CREATE); AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); 
+7
android android-intent android-studio android-service
source share
4 answers

A service can be stopped from any running class, provided that you must have a context. In the following steps, you can stop a running service at a specific time using Receiver .

1. Create a WakefulBroadcastReceiver class in your application. . Upon receipt of the action, check whether the service is running or not, if the launch completes using Context .

 public class TestReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equalsIgnoreCase("STOP_TEST_SERVICE")) { if (isMyServiceRunning(context, TestService.class)) { Toast.makeText(context,"Service is running!! Stopping...",Toast.LENGTH_LONG).show(); context.stopService(new Intent(context, TestService.class)); } else { Toast.makeText(context,"Service not running",Toast.LENGTH_LONG).show(); } } } private boolean isMyServiceRunning(Context context,Class<?> serviceClass) { ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.getName().equals(service.service.getClassName())) { return true; } } return false; } 

}

2. Register the receiver in AndroidManifest.

 <receiver android:name=".TestReceiver"> <intent-filter> <action android:name="STOP_TEST_SERVICE" /> <action android:name="START_TEST_SERVICE" /> </intent-filter> </receiver> 

3.Create a PendingIntent with the desired action, then set the scheduled action using the AlarmManager in your activity class.

  public void setStopServiceAlarm() { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 15); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 0); AlarmManager alarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent().setAction("STOP_TEST_SERVICE"), PendingIntent.FLAG_UPDATE_CURRENT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } else { alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } } 

Hope this helps!

+8
source share

In the same way.

When Service starts with Intent (or through PendingIntent ), Android will start the service, if necessary, call onCreate() if this happens, and then the onStartCommand(intent, flags, startId) , passing Intent and startId .

Service must manage its own life cycle and call stopSelf() , when this is done, when the service is destroyed by Android, the onDestroy() method is onDestroy() .

The only way to start a service is to bind to it from Activity . This does not call onStartCommand() ; instead, it calls onBind() .

Android terminates the service if

  • service call stopSelf() and not bound to it Activity
  • the service is not tied to Activity, there are no other links and other commands for which stopSelf() not been called
  • Low resources on the device ( START_STICKY flags and these flags are used here)

The stopSelf() method has a version of stopSelf(int) . A call without parameters means: I finished with everyone, stopped me; calling it with an integer value: I do if after that no other command was received; the integer is one of the startId that you get in the onStartCommand() method. If you have a queue of operations executed one after another, it is natural to call stopSelf(int) after each operation, otherwise your Service should know when to call stop.

Thus, usually a Service should โ€œknowโ€ what it is doing and stop when it is finished, but you can start the Intent with a specific action (say "ACTION_STOP") for this Service and process this action stopSelf() If it was started, this will stop it (it is your responsibility to close any background thread / release any resource, possibly in onDestroy() ). If it has not been started, it will start and stop immediately.

It says that I invite you to think about what you are doing. You didnโ€™t specify, but your request is a bit strange, I canโ€™t think of a reason why the service should be scheduled to close.

Finally, consider JobScheduler look at JobScheduler for Lollipop and later. It is better to use a battery.

+2
source share

I agree with Daniel - your service must know when to stop and stop on the timer, this is strange. However, to stop the service at a specific time every day, you can simply send an additional service. When the Service sees additional information, it knows that it is necessary to stop.

Using essentially your code,

 Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 9); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); // set the time when youre supposed to stop Intent serviceIntent = new Intent(getApplicationContext(), Service.class); serviceIntent.setAction("stop"); PendingIntent pi = PendingIntent.getService(getApplicationContext(), 0, serviceIntent, PendingIntent.FLAG_NO_CREATE); AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); 

and in your onStartCommand service you just do something like

 public void onStartCommand() { if("stop".equals(intent.getAction)) { stopSelf(); return; } else { // do whatever you were doing } } 

Try to use constants instead of letters as "stop", although after this good practice.

+1
source share

How to stop the service.

  Intent intent = new Intent(getAppContext(), MyService.class); getAppContext().stopService(intent); 
-2
source share

All Articles