实现 Android 11 的 startForegroundService startForeground

简介

在 Android 11 及更高版本中,为了提高应用的前台服务优先级和可靠性,引入了新的方法 startForegroundService()startForeground()。本文将教你如何在 Android 11 中正确实现 startForegroundService()startForeground()

流程

下面是实现该功能的整体流程:

步骤 操作
步骤1 在 AndroidManifest.xml 文件中声明服务
步骤2 在服务的 onCreate() 方法中调用 startForegroundService()
步骤3 在服务的 onStartCommand() 方法中调用 startForeground()
步骤4 在服务的 onDestroy() 方法中调用 stopForeground() 和 stopSelf()

操作步骤

步骤1:在 AndroidManifest.xml 文件中声明服务

在你的应用的 AndroidManifest.xml 文件中添加以下代码:

<service
    android:name=".YourService"
    android:foregroundServiceType="mediaProjection|location|camera|microphone"
    android:stopWithTask="true" />

这里的 YourService 是你的服务的类名,foregroundServiceType 是服务的类型,根据你的需求选择合适的类型,例如 mediaProjectionlocationcameramicrophone 等。

步骤2:在服务的 onCreate() 方法中调用 startForegroundService()

在你的服务的 onCreate() 方法中添加以下代码:

@Override
public void onCreate() {
    super.onCreate();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(new Intent(this, YourService.class));
    } else {
        startService(new Intent(this, YourService.class));
    }
}

这里使用了 startForegroundService() 方法来启动服务,如果设备运行的是 Android 11 及更高版本,则使用该方法;否则使用 startService() 方法启动服务。

步骤3:在服务的 onStartCommand() 方法中调用 startForeground()

在你的服务的 onStartCommand() 方法中添加以下代码:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT);
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(channel);
        Notification notification = new NotificationCompat.Builder(this, "channel_id")
                .setContentTitle("Foreground Service")
                .setContentText("Service is running in the foreground")
                .setSmallIcon(R.drawable.ic_notification)
                .build();
        startForeground(1, notification);
    } else {
        startForeground(1, new Notification());
    }
    return START_STICKY;
}

在 Android 11 及更高版本中,必须先创建一个通知渠道,然后使用该渠道创建通知。上面的代码中创建了一个名为 "channel_id" 的通知渠道,并创建了一个包含标题、内容和图标的通知。最后使用 startForeground() 方法将服务设置为前台服务。

步骤4:在服务的 onDestroy() 方法中调用 stopForeground() 和 stopSelf()

在你的服务的 onDestroy() 方法中添加以下代码:

@Override
public void onDestroy() {
    super.onDestroy();
    stopForeground(true);
    stopSelf();
}

在服务销毁时,使用 stopForeground() 将服务从前台移除,并使用 stopSelf() 停止服务。

状态图

下面是实现该功能的状态图:

stateDiagram
    [*] --> Idle
    Idle --> ForegroundService : onCreate()
    ForegroundService --> Foreground : onStartCommand()
    Foreground --> Background : onDestroy()
    Background --> Idle

序列图

下面是实现该功能的序列图:

sequenceDiagram
    participant YourService
    participant NotificationManager
    participant NotificationCompat
    participant ForegroundService

    Note right of YourService: onCreate()
    YourService ->> ForegroundService: startForegroundService()

    Note right of ForegroundService: onStartCommand()
    ForegroundService ->> NotificationManager: createNotificationChannel()
    ForegroundService ->> NotificationManager: create notification
    ForegroundService ->> ForegroundService: startForeground()

    Note right of YourService: onDestroy()
    YourService ->> ForegroundService: stopForeground()
    YourService ->> ForegroundService: stopSelf()

结论

本文介绍了在 Android 11 中实现 startForegroundService()startForeground() 的步骤