如何在一天中的特定时间停止服务?
How to stop a service at a specific time of the day?
我已经能够在每天的特定时间启动服务,但我想做完全相同的事情来停止,但我不知道如何做。
这是我使用 AlarmManager 启动服务的代码。
注意:我是 android 开发人员的新手,因此非常感谢提供完整的注释代码。
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);
我如何停止服务。
Intent intent = new Intent(getAppContext(), MyService.class);
getAppContext().stopService(intent);
同理。
当您使用 Intent
(或通过 PendingIntent
)启动 Service
时,如果需要 Android 启动服务,将调用 onCreate()
就是这样,然后 onStartCommand(intent, flags, startId)
方法传递 Intent
和 startId
.
Service
应该管理自己的生命周期并在完成时调用 stopSelf()
,当服务被 Android 销毁时,调用 onDestroy()
方法。
启动服务的唯一其他方法是从 Activity
绑定 到它。这不会触发对 onStartCommand()
的调用,而是调用 onBind()
。
Android 如果
终止服务
- 服务调用
stopSelf()
并且没有 Activity
绑定到它
- 该服务已从 Activity 解除绑定,没有其他绑定或其他未调用
stopSelf()
的命令
- 设备资源不足(这是
START_STICKY
标志和那些标志发挥作用的地方)
stopSelf()
方法有一个 stopSelf(int)
版本。不带参数调用的意思是:我都搞定了,别打我了;用整数调用它意味着:如果在此之后没有收到其他命令,我就完成了;该整数是您在 onStartCommand()
方法中获得的 startId
之一。如果你有一个操作队列 运行 一个接一个地调用 stopSelf(int)
自然是在每个操作有 运行 之后,否则你的 Service
需要知道什么时候调用停止。
所以通常 Service
应该 "know" 它正在做什么并在完成后自行停止,但您可以启动具有特定操作的 Intent
(比如 "ACTION_STOP")
对于 Service
并处理调用 stopSelf()
的操作。如果它是 运行ning 这将停止它(您有责任关闭任何后台线程/释放任何资源,可能在 onDestroy()
). 如果不是 运行ning 它将启动并立即停止。
也就是说,我邀请您考虑一下您在做什么。您没有指定,但您的要求有点奇怪,我想不出应该安排服务关闭的原因。
最后,考虑查看 JobScheduler
for Lollipop 及更高版本。更利于电池使用。
我同意 Daniele 的观点 - 你的服务应该知道什么时候停止自己并且在计时器上停止它很奇怪。也就是说,要在每天的特定时间停止服务,您只需向您的服务发送额外的费用即可。当服务看到多余的内容时,它知道停止。
使用本质上是您的代码,
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);
并且在您服务的 onStartCommand 中,您只需执行类似
的操作
public void onStartCommand()
{
if("stop".equals(intent.getAction))
{
stopSelf();
return;
}
else {
// do whatever you were doing
}
}
尝试使用常量而不是像 "stop" 这样的文字,尽管这是一种很好的做法。
可以从任何 运行 class 停止服务,前提是您应该有上下文。
通过以下步骤,您可以使用 Receiver.
在特定时间停止 运行 服务
1.在您的应用程序中创建一个 WakefulBroadcastReceiver class。 在接收操作时检查服务是否 运行,如果 运行 停止使用 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。在 AndroidManifest.
中注册接收器
<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="STOP_TEST_SERVICE" />
<action android:name="START_TEST_SERVICE" />
</intent-filter>
</receiver>
3.Create PendingIntent with desired action, then set scheduled action using AlarmManager 在你的 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);
}
}
希望对您有所帮助!!
我已经能够在每天的特定时间启动服务,但我想做完全相同的事情来停止,但我不知道如何做。
这是我使用 AlarmManager 启动服务的代码。
注意:我是 android 开发人员的新手,因此非常感谢提供完整的注释代码。
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);
我如何停止服务。
Intent intent = new Intent(getAppContext(), MyService.class);
getAppContext().stopService(intent);
同理。
当您使用 Intent
(或通过 PendingIntent
)启动 Service
时,如果需要 Android 启动服务,将调用 onCreate()
就是这样,然后 onStartCommand(intent, flags, startId)
方法传递 Intent
和 startId
.
Service
应该管理自己的生命周期并在完成时调用 stopSelf()
,当服务被 Android 销毁时,调用 onDestroy()
方法。
启动服务的唯一其他方法是从 Activity
绑定 到它。这不会触发对 onStartCommand()
的调用,而是调用 onBind()
。
Android 如果
终止服务- 服务调用
stopSelf()
并且没有Activity
绑定到它 - 该服务已从 Activity 解除绑定,没有其他绑定或其他未调用
stopSelf()
的命令 - 设备资源不足(这是
START_STICKY
标志和那些标志发挥作用的地方)
stopSelf()
方法有一个 stopSelf(int)
版本。不带参数调用的意思是:我都搞定了,别打我了;用整数调用它意味着:如果在此之后没有收到其他命令,我就完成了;该整数是您在 onStartCommand()
方法中获得的 startId
之一。如果你有一个操作队列 运行 一个接一个地调用 stopSelf(int)
自然是在每个操作有 运行 之后,否则你的 Service
需要知道什么时候调用停止。
所以通常 Service
应该 "know" 它正在做什么并在完成后自行停止,但您可以启动具有特定操作的 Intent
(比如 "ACTION_STOP")
对于 Service
并处理调用 stopSelf()
的操作。如果它是 运行ning 这将停止它(您有责任关闭任何后台线程/释放任何资源,可能在 onDestroy()
). 如果不是 运行ning 它将启动并立即停止。
也就是说,我邀请您考虑一下您在做什么。您没有指定,但您的要求有点奇怪,我想不出应该安排服务关闭的原因。
最后,考虑查看 JobScheduler
for Lollipop 及更高版本。更利于电池使用。
我同意 Daniele 的观点 - 你的服务应该知道什么时候停止自己并且在计时器上停止它很奇怪。也就是说,要在每天的特定时间停止服务,您只需向您的服务发送额外的费用即可。当服务看到多余的内容时,它知道停止。
使用本质上是您的代码,
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);
并且在您服务的 onStartCommand 中,您只需执行类似
的操作public void onStartCommand()
{
if("stop".equals(intent.getAction))
{
stopSelf();
return;
}
else {
// do whatever you were doing
}
}
尝试使用常量而不是像 "stop" 这样的文字,尽管这是一种很好的做法。
可以从任何 运行 class 停止服务,前提是您应该有上下文。 通过以下步骤,您可以使用 Receiver.
在特定时间停止 运行 服务1.在您的应用程序中创建一个 WakefulBroadcastReceiver class。 在接收操作时检查服务是否 运行,如果 运行 停止使用 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。在 AndroidManifest.
中注册接收器<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="STOP_TEST_SERVICE" />
<action android:name="START_TEST_SERVICE" />
</intent-filter>
</receiver>
3.Create PendingIntent with desired action, then set scheduled action using AlarmManager 在你的 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);
}
}
希望对您有所帮助!!