如何在一天中的特定时间停止服务?

时间:2016-03-13 17:28:58

标签: android android-intent android-studio android-service

我已经能够在每天的特定时间开始服务,但我想做同样的事情停止但我不知道如何。

以下是我使用AlarmManager启动服务的代码 注意:我是Android dev的新手,因此提供完整的评论代码将受到高度赞赏。

 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);

4 个答案:

答案 0 :(得分:8)

只要您拥有上下文,就可以从任何正在运行的类中停止服务。 通过以下步骤,您可以使用 Receiver 在特定时间停止正在运行的服务。

<强> 1。在您的应用程序中创建一个WakefulBroadcastReceiver类。在接收操作时检查服务是否正在运行,如果使用上下文运行停止。

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.使用所需操作创建PendingIntent,然后在您的活动类中使用AlarmManager设置预定操作。

 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);
    }
}

希望这会有所帮助!!

答案 1 :(得分:2)

以同样的方式。

当您使用Service启动Intent时(或通过PendingIntent)Android启动服务(如果需要),如果是这种情况,则会调用onCreate(),然后传递onStartCommand(intent, flags, startId)Intent的{​​{1}}方法。

startId应该管理自己的生命周期,并在完成后调用Service,当Android销毁服务时,调用stopSelf()方法。

启动服务的唯一其他方式是从onDestroy() 绑定。这不会触发对Activity的调用,而是调用onStartCommand()

如果

,Android会终止该服务
  • 服务电话onBind()并且没有绑定stopSelf()
  • 服务从一个Activity解除绑定,没有其他绑定或其他命令Activity尚未被调用
  • 设备上的资源不足(这是stopSelf()标志和那些标志发挥作用的地方)

START_STICKY方法的版本为stopSelf()。不带参数调用它意味着:我已经完成了所有,阻止我;用整数调用它意味着:如果在此之后没有收到其他命令,我就完成了;整数是stopSelf(int)方法中的startId之一。如果您有一个接一个地运行的操作队列,则在每个操作运行后调用onStartCommand()是很自然的,否则您的stopSelf(int)需要知道何时调用停止。

通常,Service应该“知道”它正在做什么,并在完成后自行停止,但是您可以使用特定操作启动Service(比如说​​Intent "ACTION_STOP") 1}}并处理调用Service的操作。如果它正在运行,这将停止它(你有责任关闭任何后台线程/释放任何资源,可能在stopSelf())。如果它没有运行它将开始并立即停止。

那说我邀请你思考你在做什么。您没有指定,但您的请求有点奇怪,我想不出应该安排服务关闭的原因。

最后,考虑一下Lollipop及其后的onDestroy()。电池使用效果更好。

答案 2 :(得分:1)

我同意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 
 }
 }

尝试使用常量而不是像“停止”这样的文字,尽管这是很好的做法。

答案 3 :(得分:-3)

我如何停止服务。

 Intent intent = new Intent(getAppContext(), MyService.class);
 getAppContext().stopService(intent);