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

ki1q1bka  于 2023-10-14  发布在  Android
关注(0)|答案(9)|浏览(274)

我试图停止一个作为前台服务运行的服务。
当前的问题是,当我调用stopService()时,通知仍然存在。
因此,在我的解决方案中,我在onCreate()中添加了一个接收器,
onReceive()方法中,我调用了stopforeground(true),它隐藏了通知。然后stopself()停止服务。
onDestroy()里面我注册了接收器。
有没有更合适的方法来处理这件事?因为stopService()根本不起作用。

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

bz4sfanl1#

1.从您的Activity中调用startService(intent)并向其传递一些表示键的数据,以停止服务
1.从您的服务,请致电stopForeground(true)
1.然后是stopSelf()

bybem2ql

bybem2ql2#

要从Activity启动和停止前台服务,用途:

//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;
}
jchrr9hc

jchrr9hc3#

如这里所述:https://developer.android.com/guide/components/services#Stopping
启动的服务必须管理自己的生命周期。也就是说,系统不会停止或销毁服务,除非它必须恢复系统内存,并且服务在**onStartCommand()返回后继续运行。服务必须通过调用stopSelf()自行停止,或者其他组件可以通过调用stopService()停止服务。
使用
stopSelf()或stopService()**请求停止后,系统会尽快销毁服务。
因此,您可以从用于调用startService()的Activity调用stopService()。我在这里做了:

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

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

wb1gzix0

wb1gzix04#

从活动

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

服务本身

stopForeground(true);
  stopSelf()
kyks70gy

kyks70gy5#

除了其他答案,我用这个片段结束使用android oreo和later停止工作服务。

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

sz81bmfz

sz81bmfz6#

如果要停止服务然后更新通知,可以先调用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);
    }
0tdrvxhp

0tdrvxhp7#

我发现停止服务的最好方法是让服务本身停止。这样,您就可以确保它实际上会停止并保持数据完整性。如果你想从外部(活动)做,我通常使用全局静态属性。
在这里检查我的答案:https://stackoverflow.com/a/57833370/7795547

z2acfund

z2acfund8#

  • 您可以从 * 服务 * 或 * 活动 * 中停止服务
    来自服务:
stopForeground(true);
 stopSelf();

来自活动:

stopService(new Intent(this, MyService.class));
//MyService is your service
ecbunoof

ecbunoof9#

如果您有一个不时(周期性地)在前台运行的任务,例如使用System.Threading.Timer,则应修改计时器,使其定期停止执行方法。
一种“停止”计时器的方法:

if (timer != null)
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
}

相关问题