I have been able to start a service at specific time of every day but I want to do the exact same thing to stop but I don't know how.
Here is the code I use to start the service using AlarmManager.
note: I am new to android dev so providing a full commented code will be highly 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);
You can add a shutdown() method into your AIDL interface, which allows an Activity to request a stopSelf() be called. This encapsulates the stopping logic and gives you the opportunity to control the state of your Service when it is stopped, similar to how you would handle a Thread .
Service can stop itself by calling methods as follows. stopSelf(): On calling it, Service is stopped if it is running. stopSelfResult(int startId): Stops the service for the most recent start id.
Fundamentals of Android ServicesOnce the service is started, it can be stopped explicitly using stopService() or stopSelf() methods.
Service can be stopped from any running class provided you should have the context. From the following steps you can stop the running service at specific time using Receiver.
1. Create a WakefulBroadcastReceiver class in your application. On receive action check if service is running or not,if running stop 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 desired action, then set scheduled action using 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!!
In the same way.
When you launch a Service
with an Intent
(or through a PendingIntent
) Android start the service if needed, will call onCreate()
if that's the case, then the onStartCommand(intent, flags, startId)
method passing the Intent
and a startId
.
The Service
is supposed to manage its own lifecycle and call stopSelf()
when it's done, when the service is destroyed by Android the onDestroy()
method is called.
The only other way of starting a Service is binding to it from an Activity
. This does not trigger a call to onStartCommand()
, it calls onBind()
instead.
Android terminate the service if
stopSelf()
and there is no Activity
binded to itstopSelf()
has not been calledSTART_STICKY
flags and those kind of flags comes into play)The stopSelf()
method has a stopSelf(int)
version. Calling it without parameters means: I'm done with all, stop me; calling it with the integer means: I'm done if no other command has been received after this one; the integer is one of the startId
you get in onStartCommand()
method. If you have a queue of operation running one after the other it is natural to call stopSelf(int)
after each operation has run, otherwise your Service
need to know when to call stop.
So usually a Service
should "know" what it is doing and stop itself when its done but you can launch an Intent
with a specific action (say "ACTION_STOP")
for that Service
and handle that action calling stopSelf()
. If it was running this will stop it (your responsibility to close any background thread / release any resource, maybe in onDestroy()
). If it wasn't running it will start and immediately stop.
That said I invite you to think about what you are doing. You didn't specified but your request is a bit weird, I can't think of a reason why a service shutdown should be scheduled.
Finally, consider having a look at JobScheduler
for Lollipop and later. It's better for battery usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With