📜  android 前台服务设置自动取消不起作用 - Java (1)

📅  最后修改于: 2023-12-03 15:29:21.738000             🧑  作者: Mango

Android 前台服务设置自动取消不起作用 - Java

前台服务是 Android 系统中一种比较特殊的服务,它可以在系统状态栏中显示一个持续运行的通知,这种服务常用于播放音乐、下载任务等需要长时间运行的任务中,以确保系统不会将其杀掉。但是有时候我们可能会遇到这样的情况:前台服务设置了自动取消,但是在实际应用中却没有起作用。本文将介绍如何解决这个问题。

1. 前台服务设置自动取消

在 Android 中,我们可以通过 startForeground 方法将一个服务设置为前台服务,并且可以通过 stopForeground 方法将其取消掉。在 startForeground 方法中,我们可以设置一个通知来显示在状态栏中,如下所示:

private void startForegroundService() {
    // 创建通知
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("前台服务")
            .build();

    // 将服务设置为前台服务,并显示通知
    startForeground(NOTIFICATION_ID, notification);
}

stopForeground 方法中,我们可以选择性地将通知也取消掉,如下所示:

private void stopForegroundService() {
    // 如果需要取消通知,需要传入true
    stopForeground(true);

    // 停止服务
    stopSelf();
}
2. 解决前台服务自动取消不起作用的问题

如果您在使用前台服务时出现了无法自动取消的问题,可能是因为您在服务中有以下两种情况中的其中一种:

2.1. 后台线程没有结束

如果您在前台服务中启动了一个后台线程,并且这个线程没有在服务停止时被正确地结束掉,那么前台服务就无法被自动取消。解决这个问题的方法很简单,只需要在服务中添加一个全局的布尔变量(比如 isStopped),并在服务停止时将其设置为 true,然后在后台线程中定期查询这个变量的值,如果已经被设置为 true,那么就立即退出线程即可。

public class MyService extends Service {
    private boolean isStopped = false;
    private Thread backgroundThread;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 启动后台线程
        backgroundThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!isStopped) {
                    // 后台线程内容
                }
                // 后台线程结束
            }
        });
        backgroundThread.start();

        // 在前台显示通知
        startForeground(NOTIFICATION_ID, new Notification());

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // 服务停止时将 isStopped 设置为 true
        isStopped = true;

        // 等待后台线程结束
        try {
            backgroundThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 取消通知并停止服务
        stopForeground(true);
        stopSelf();
    }
}
2.2. Android 版本过高

在 Android 8.0 及以上的版本中,系统对前台服务的限制更加严格,如果您的应用在启动前台服务时没有为其创建一个通知渠道,系统就会将其视为后台服务并将其杀掉。所以,如果您的应用在 Android 8.0 及以上的版本中运行,并且前台服务无法自动取消,那么很可能是因为您没有为其创建一个通知渠道。

要解决这个问题,您需要在启动前台服务前,先创建一个通知渠道:

private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // 创建通知渠道
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "前台服务", NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("这是一个前台服务");
        channel.enableLights(false);
        channel.enableVibration(false);
        channel.setSound(null, null);

        // 注册通知渠道
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

然后在启动前台服务时,指定这个通知渠道即可:

private void startForegroundService() {
    // 创建通知
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("前台服务")
            .build();

    // 将服务设置为前台服务,并显示通知
    startForeground(NOTIFICATION_ID, notification);
}
结语

通过本文,您应该已经了解到如何解决前台服务自动取消不起作用的问题了。具体而言,您需要检查您的服务中是否有未正确结束的后台线程,并且如果您的应用在 Android 8.0 及以上的版本中运行,您还需要为前台服务创建一个通知渠道。如果您在实际应用中遇到了其他问题,欢迎在评论区留言,我会尽力为您解答。