【问题标题】:How to stop a service at a specific time of the day?如何在一天中的特定时间停止服务?
【发布时间】:2016-03-13 17:28:58
【问题描述】:

我已经能够在每天的特定时间启动服务,但我想做完全相同的事情来停止,但我不知道如何。


这是我使用 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);

【问题讨论】:

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


【解决方案1】:

只要您有上下文,就可以从任何正在运行的类中停止服务。 通过以下步骤,您可以使用 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);
    }
}

希望这有帮助!

【讨论】:

  • 像冠军一样工作!你应该得到 50 分 ;) 但是我可以问你,你是如何专门在 android 平台上学习 java 的,因为我是初学者,老实说我不知道​​从哪里开始学习!
  • @Mouyahama,我从“thenewboston”系列视频开始学习android(链接:youtube.com/playlist?list=PL2F07DBCDCC01493A)。您可以从基本应用开始,在 stackoverflow 上提出任何问题,大多数与 android 相关的基本问题都已在此处得到解答。还可以查看 Vogella android 教程(链接:vogella.com/tutorials/android.html)。感谢您接受我的回答。{EnjoyAndroid}
【解决方案2】:

以同样的方式。

当您使用Intent(或通过PendingIntent)启动Service 时,如果需要,Android 会启动服务,如果是这种情况,将调用onCreate(),然后onStartCommand(intent, flags, startId) 方法传递@987654326 @ 和 startId

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

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

Android 终止服务如果

  • 服务调用stopSelf(),但没有绑定Activity
  • 服务未与 Activity 绑定,没有其他绑定或未调用 stopSelf() 的其他命令
  • 设备资源不足(这是START_STICKY 标志和此类标志发挥作用的地方)

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

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

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

最后,考虑查看 JobScheduler 的 Lollipop 及更高版本。这对电池使用更好。

【讨论】:

    【解决方案3】:

    我同意 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”这样的字面量,因为这是一种很好的做法。

    【讨论】:

    【解决方案4】:

    我如何停止服务。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多