API>25 中的前台服务在应用程序运行(可见)时是否强制通知

Vor*_*avi 2 android foreground-service android-8.0-oreo

从 stackoverflow 和许多博客中,我确信前台服务在 API>25 中永远不会在没有通知的情况下运行。但我仍然感到困惑,当应用程序在屏幕上运行或可见时,通知是否是强制的。例如。当用户站在应用程序内时无需通知。那么这可以在应用程序运行时删除通知吗? 在服务舱

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    ......
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(text)
                .setAutoCancel(true);

        Notification notification = builder.build();
        startForeground(1, notification);

    } 
return START_NOT_STICKY;
}
Run Code Online (Sandbox Code Playgroud)

活动中

Intent myService = new Intent(this, MyService.class);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(myService);
    } else {
        startService(myService);
    }
Run Code Online (Sandbox Code Playgroud)

gre*_*e31 5

在前台服务运行时无法删除通知,但可以前台服务更改回“常规”服务。这消除了对通知的需要。事实上,要使用的功能,

stopForeground(boolean removeNotification)

...包括一个removeNotification仅用于此目的的参数。startForeground()通过交替调用和,您的服务可以根据需要从“前台”切换到“常规” stopForeground()

如果不清楚,您可能希望stopForeground()在至少有一个Activity处于“已启动”状态时致电。这是您必须手动跟踪的事情。然后,当“已启动”活动的数量达到 0 时,您将调用startForeground().

编辑

一种方法是使用绑定服务。stopForeground()然后,您可以在需要时轻松调用它。

假设您有一个活动。您可以将其绑定到服务(请参阅此文档或使用这些示例之一)。那么你的onServiceConnected()函数可能如下所示(改编自 Google 示例):

//MyActivity.java:

@Override
public void onServiceConnected(ComponentName className, IBinder service) {
    LocalBinder binder = (LocalBinder) service;
    mService = binder.getService();
    mService.stopForeground(true);      //This makes the notification go away
    bound = true;
}

...

@Override
protected void onStart() {
    super.onStart();
    // Bind to the service
    bindService(new Intent(this, MyService.class), this, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (bound) {
        Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(text)
            .setAutoCancel(true);

        Notification notification = builder.build();
        mService.startForeground(1, notification);    //This brings the notification back! Service is already running, and continues to run.        

        unbindService(this);
        bound = false;
    }
}
Run Code Online (Sandbox Code Playgroud)