什么是停止作为前台运行的服务的正确方法

时间:2013-12-31 12:04:33

标签: android foreground-service

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

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

所以在我的解决方案中,我添加了一个我在onCreate()

内注册的接收器

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

onDestroy()内,我取消了注册接收者。

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

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

7 个答案:

答案 0 :(得分:46)

在您的活动中致电startService(intent)并向其传递一些数据,这些数据代表停止服务的关键。

在您的服务电话stopForeground(true)之后,然后是stopSelf()

答案 1 :(得分:22)

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

//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);
        stopSelf();
    }
    return START_STICKY;
}

答案 2 :(得分:3)

如此处所述: 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))
    }

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

答案 3 :(得分:2)

来自活动

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

来自服务本身

  stopForeground(true);
  stopSelf()

答案 4 :(得分:0)

除了其他答案外,我还使用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

答案 5 :(得分:0)

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

    @Test
    public void disposeWhenFallback() {
        TestScheduler sch = new TestScheduler();

        SingleSubject<Integer> subj = SingleSubject.create();

        subj.timeout(1, TimeUnit.SECONDS, sch, Single.just(1))
        .test(true)
        .assertEmpty();

        assertFalse(subj.hasObservers());
    }

答案 6 :(得分:0)

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

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