65

我正在尝试停止作为前台服务运行的服务。

当前的问题是,当我打电话时stopService(),通知仍然存在。

所以在我的解决方案中,我添加了一个接收器,我正在注册到onCreate()

onReceive()我调用的方法中stopforeground(true),它隐藏了通知。然后stopself()停止服务。

在里面onDestroy()我注销了接收器。

有没有更合适的方法来处理这个?因为 stopService() 根本不起作用。

@Override
public void onDestroy(){
  unregisterReceiver(receiver);
  super.onDestroy();
}
4

7 回答 7

91

从您的活动调用startService(intent)中传递一些数据,这些数据将代表停止服务的键。

从您的服务电话stopForeground(true)开始,然后stopSelf()在它之后。

于 2013-12-31T12:22:58.133 回答
59

从活动使用启动和停止前台服务:

//start
    Intent startIntent = new Intent(MainActivity.this, ForegroundService.class);
    startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
    startService(startIntent);
//stop
    Intent stopIntent = new Intent(MainActivity.this, ForegroundService.class);
    stopIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
    startService(stopIntent);

在您的前台服务中 - 使用(至少)此代码:

@Override
 public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
        Log.i(LOG_TAG, "Received Start Foreground Intent ");
        // your start service code
    }
    else if (intent.getAction().equals( Constants.ACTION.STOPFOREGROUND_ACTION)) {
        Log.i(LOG_TAG, "Received Stop Foreground Intent");
    //your end servce code
        stopForeground(true);
        stopSelfResult(startId);
    }
    return START_STICKY;
}
于 2018-06-16T14:02:25.490 回答
14

如此处所述: https ://developer.android.com/guide/components/services#Stopping

已启动的服务必须管理自己的生命周期。也就是说,系统不会停止或销毁服务,除非它必须恢复系统内存并且服务在onStartCommand()返回后继续运行。服务必须通过调用stopSelf()来停止自己,或者另一个组件可以通过调用stopService()来停止它。

一旦使用stopSelf() 或 stopService()请求停止,系统会尽快销毁服务。

因此,您可以从您用来调用 startService() 的活动中调用 stopService()。我在这里做到了:

start_button.setOnClickListener {
            applicationContext.startForegroundService(Intent(this, ServiceTest::class.java))
        }
stop_button.setOnClickListener {
            applicationContext.stopService(Intent(this, ServiceTest::class.java))
        }

我创建了两个按钮来启动和停止服务,它可以工作。

于 2019-08-06T04:23:47.790 回答
9

从活动

 stopService(new Intent(this, ForegroundService.class));

从服务本身

  stopForeground(true);
  stopSelf()
于 2020-03-30T09:53:59.040 回答
3

除了其他答案之外,我还使用 android oreo 和更高版本来停止作业服务。

Intent intent = new Intent(getApplicationContext(), LocationService.class);
intent.setAction(status);
ContextCompat.startForegroundService(getApplicationContext(), intent);

并在服务中

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
  startForeground(121, notification);
  if (intent.getAction().equals("StopService")) {
    stopForeground(true);
    stopSelf();
  }

startForeground() 是强制性的,除非应用程序在不调用它的情况下崩溃

新的 Context.startForegroundService() 方法启动前台服务。即使应用在后台,系统也允许应用调用 Context.startForegroundService()。但是,应用程序必须在服务创建后五秒内调用该服务的 startForeground() 方法。

https://developer.android.com/about/versions/oreo/android-8.0-changes.html

于 2019-03-17T15:06:06.760 回答
0

如果你想停止服务然后更新通知,你可以先调用 stopSelf() 再调用 notify()。stopForeground(false) 使通知可取消。

 private final BroadcastReceiver myBgWorkCompleteReceiver= new BroadcastReceiver() {
        @Override
  public void onReceive(Context context, Intent intent) {
            stopSelf();
            notificationLayoutExpanded.setTextViewText(R.id.file_download_notify_download_percentage, "Background work completed");
            manager.notify(mNotificationId, notification);
            stopForeground(false);
        }
};


 public void onDestroy() {
        super.onDestroy();
        // cancel any running threads here
        LocalBroadcastManager.getInstance(this).unregisterReceiver(myBgWorkCompleteReceiver);
    }
于 2019-09-04T07:41:06.947 回答
0

我发现停止服务的最佳方法是自行停止。这样您就可以确定它实际上会停止并保持数据完整性。如果您想从外部(活动)执行此操作,我通常使用全局静态属性。

在这里查看我的答案:https ://stackoverflow.com/a/57833370/7795547

于 2019-09-07T13:25:13.143 回答