当前位置:   article > 正文

Android 前台服务

android 前台服务

一、什么是前台服务?

前台服务(Foreground Service)是一种在 Android 应用程序中执行长时间运行任务的服务类型。与普通的后台服务不同,前台服务在系统通知栏中显示一个可见的通知,向用户表明应用程序正在进行某项重要的操作,以便用户知晓并提供更好的用户体验。

前台服务通常用于执行用户可感知的任务,例如播放音乐、下载文件、进行定位更新等。通过将服务置于前台状态并显示通知,前台服务可以避免被系统误认为是低优先级的后台任务,从而更好地确保服务的稳定运行。

前台服务的特点包括:

  1. 显示通知:前台服务必须显示一个可见的通知,以向用户展示服务正在执行的操作。

  2. 优先级提升:前台服务的优先级比普通后台服务更高,可以获得更多的系统资源,例如 CPU 时间和网络带宽。

  3. 用户可见性:前台服务通知在系统通知栏中显示,并且用户可以通过通知进行交互。

在 Android 8.0(API 级别 26)及更高版本中,引入了对后台服务的限制,要求应用程序使用前台服务来执行某些操作。这是为了提高系统资源的管理和保护用户的隐私。

如果您的应用程序需要在后台执行长时间运行的任务,并且这些任务对用户可见或需要保持运行状态,那么您可能需要使用前台服务来实现这些功能。

  • 例如,内存清理软件清理内存,如果不是前台服务,就会被清理掉。
    通过测试,发现360手机卫士的强力加速会杀掉没有前台服务的应用,但是有前台服务,就不能被杀掉了。

二、为什么使用前台服务?

使用前台服务的主要目的是改善用户体验和满足系统对后台任务的限制。以下是一些使用前台服务的常见情况和好处:

  1. 持续运行任务:前台服务允许您在后台执行长时间运行的任务,而不会受到系统对后台任务的限制。例如,播放音乐、下载文件、进行定位更新等任务可以在前台服务中执行,并且可以持续运行,即使应用程序处于后台或设备锁定状态。

  2. 用户可见性:前台服务通过显示一个可见的通知,将正在执行的任务展示给用户。这样,用户可以清楚地知道应用程序正在进行某些重要操作,并且可以通过通知与应用程序进行交互。这提高了用户对应用程序的可见性和控制权,让用户更好地理解和参与应用程序的运行。

  3. 系统资源优化:前台服务通常会获得更多的系统资源,例如 CPU 时间和网络带宽。这可以确保您的任务在需要时具有足够的计算和通信能力,并且可以更稳定地执行任务,提供更好的性能和响应性。

  4. 合规性要求:在某些情况下,特定的应用程序类型或功能可能需要使用前台服务来满足合规性要求。例如,某些地区的隐私法规可能要求在执行某些任务时向用户显示通知,并获得其明确的许可。

需要注意的是,使用前台服务可能会增加应用程序的电池消耗,因为持续运行任务需要持续的系统资源。因此,您应该仔细考虑使用前台服务的必要性,并合理管理资源以平衡功能需求和用户体验。

总而言之,使用前台服务可以提供更好的用户体验、满足系统对后台任务的限制,并提供更高的可见性和控制权。通过合理地使用前台服务,您可以实现长时间运行的任务并保持应用程序的稳定性和响应性。

三、调用

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • 1

否则会出现异常:

java.lang.SecurityException: Permission Denial:
 startForeground from pid=2345, uid=10395 requires android.permission.FOREGROUND_SERVICE.
  • 1
  • 2

Service

public class ForeService extends Service {

    private static final String TAG = "ForeService";

    public ForeService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        AppLogUtils.input(TAG, "onCreate ..");
    }

    @Override
    public IBinder onBind(Intent intent) {
        AppLogUtils.input(TAG, "onBind ..");
        return new Binder();
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
        AppLogUtils.input(TAG, "onRebind ..");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        AppLogUtils.input(TAG, "onStartCommand ..");

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext()).setAutoCancel(true);// 点击后让通知将消失
        mBuilder.setContentText("测试");
        mBuilder.setContentTitle("测试");
        mBuilder.setSmallIcon(R.mipmap.lu4);
        mBuilder.setWhen(System.currentTimeMillis());//通知产生的时间,会在通知信息里显示
        mBuilder.setPriority(Notification.PRIORITY_DEFAULT);//设置该通知优先级
        mBuilder.setOngoing(false);//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
        mBuilder.setDefaults(Notification.DEFAULT_ALL);//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            String channelId = "channelId" + System.currentTimeMillis();
            NotificationChannel channel = new NotificationChannel(channelId, getResources().getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH);
            manager.createNotificationChannel(channel);
            mBuilder.setChannelId(channelId);
        }
        mBuilder.setContentIntent(null);
        startForeground(222, mBuilder.build());
        

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        AppLogUtils.input(TAG, "onDestroy ..");
        stopForeground(true);// 停止前台服务--参数:表示是否移除之前的通知
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

注意:在启动前台服务后,请务必在适当的时机调用 stopForeground(true) 或 stopForeground(STOP_FOREGROUND_REMOVE) 方法来停止前台服务并移除通知。这可以避免长时间运行的前台服务对电池寿命和系统资源的影响。

  • 启用服务
                    Intent intent = new Intent().setClass(getActivity(), ForeService.class);
                    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        startForegroundService(intent);
                    } else {
                        startService(intent);
                    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

使用startxxxxService() 是为了调用 onStartCommand(***)

  • 终止服务
unBindService + stopService
  • 1

一定要调用 stopService 否则无法再次绑定

四、Android 版本更新变换

Android 2.0

前台服务(Foreground Service)是在Android 2.0(API级别5)中引入的

Android 8

在 Android 8.0(API 级别 26)及更高版本中,引入了对后台服务的限制,要求应用程序使用前台服务来执行某些操作。这是为了提高系统资源的管理和保护用户的隐私。

Android 9 目标平台

https://blog.csdn.net/weixin_35691921/article/details/131123111?spm=1001.2014.3001.5501

如果应用以 Android 9 或更高版本为目标平台并使用前台服务,则必须请求 FOREGROUND_SERVICE 权限。这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

Android 11 目标平台

https://blog.csdn.net/weixin_35691921/article/details/130867600?spm=1001.2014.3001.5501

转:https://developer.android.google.cn/about/versions/11/privacy/foreground-services?hl=zh-cn

在 Android 11 中,前台服务何时可以访问设备的位置信息、摄像头和麦克风发生了一些变化。这有助于保护敏感的用户数据。

  • 前台服务类型 cameramicrophone
    如果您的应用以 Android 11 或更高版本为目标平台,且在前台服务中访问摄像头或麦克风,则必须添加前台服务类型 cameramicrophone
    - 对在使用时访问的限制
    如果您的应用在后台运行时启动了某项前台服务,则该前台服务无法访问麦克风或摄像头。此外,除非您的应用具有在后台访问位置信息的权限,否则该服务无法访问位置信息。
  • Android 12 已经无法再后台启动前台服务

Android 12 平台

Android 12 平台及以上版本

https://blog.csdn.net/weixin_35691921/article/details/130830473?spm=1001.2014.3001.5501

前台服务通知的用户体验延迟

Android 12 目标平台

https://developer.android.google.cn/about/versions/12/behavior-changes-12?hl=zh-cn#foreground-service-launch-restrictions

前台服务启动限制(无法在后台运行时启动前台服务)

以 Android 12 或更高版本为目标平台的应用无法在后台运行时启动前台服务,少数特殊情况除外。如果应用尝试在后台运行时启动前台服务,则会引发异常(少数特殊情况除外)。

当您的应用在后台运行时,请考虑使用 WorkManager 来计划和启动加急工作。如需完成用户请求的紧急操作,请按照精确的闹钟启动前台服务。

Android 13 平台及以上,用户可以退出前台服务

https://blog.csdn.net/weixin_35691921/article/details/130882872?spm=1001.2014.3001.5501

android 13 及以上版本,用户可以点击停止前台服务,这个时候

  • 系统将从内存中删除应用程序。因此,你的整个应用程序停止,而不仅仅是运行的前台服务。
  • 系统会移除应用的activity back stack
  • 任何媒体播放停止。
  • 与前台服务关联的通知被删除。
  • 你的应用会留在历史中。
  • Scheduled jobs 在计划时间执行。
  • Alarms 会在预定的时间或时间窗口响起。

Android 14 作为目标平台,必填服务类型

https://blog.csdn.net/weixin_35691921/article/details/130970609?spm=1001.2014.3001.5501

以 Android 14 或更高版本为目标平台的应用,前台服务类型是必填项。

转:https://developer.android.google.cn/about/versions/14/changes/fgs-types-required?hl=zh-cn

为了帮助开发者更有目的地定义面向用户的前台服务,Android 10 在 元素内引入了 android:foregroundServiceType 属性。

如果您的应用以 Android 14 为目标平台,则必须指定适当的前台服务类型。与以前的 Android 版本一样,可组合使用多个类型。下面列出了可供选择的前台服务类型:

  • camera
  • connectedDevice
  • dataSync
  • health
  • location
  • mediaPlayback
  • mediaProjection
  • microphone
  • phoneCall
  • remoteMessaging
  • shortService
  • specialUse
  • systemExempted

如果应用中的用例与这些类型均不相关,强烈建议您迁移逻辑以使用 WorkManager 或用户发起的数据传输作业。

Android 14 中新增了 health, remoteMessaging, shortService, specialUse 和 systemExempted 类型。

以下代码段提供了一个清单中的前台服务类型声明示例:

<manifest ...>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
    <application ...>
      <service
          android:name=".MyMediaPlaybackService"
          android:foregroundServiceType="mediaPlayback"
          android:exported="false">
      </service>
    </application>
</manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

参考地址

【Android】Service前台服务的使用 : https://blog.csdn.net/yx1166/article/details/120907911

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/464446
推荐阅读
相关标签
  

闽ICP备14008679号