Android 启动前台服务的实现方法与注意事项

2023-05-16

问题描述

Android R平台 收音机启动前台服务 startForegroundService() 报错

E AndroidRuntime: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{990dd99 u0 com.android.fmradio/.FmService}

问题分析

在Android O中,有一个新的背景限制。尝试启动startService()时,将获得IlleagalStateException,因此现在应使用startForegroundService(),但是如果通过此新方法启动服务,则会在屏幕截图中看到类似的错误。为避免此异常,您需要在startForegroundService()之后有5秒钟的时间来创建startForeground(),以通知用户您正在后台工作。否则将崩溃出现这样的崩溃信息。

使用方法

  1. 权限

启动前台服务需要添加如下权限:

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

这是一个自 Android 9.0 (API level 28) 引入的新权限,用于确保应用程序不会在未经用户许可的情况下创建前台服务。如果您的应用程序未声明此权限并尝试启动前台服务,则可能会引发 SecurityException 异常。

需注意,自Android O(API级别26)以后,仅仅在AndroidManifest.xml中声明权限是不够的,还必须在代码中请求权限。可以按以下方式检查和请求权限:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE)
        != PackageManager.PERMISSION_GRANTED) {
    // Permission not yet granted, request it
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.FOREGROUND_SERVICE},
            MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE);
}
  1. 启动服务

在 Android 8.0 及以上版本,为了遵循后台限制策略,应用程序必须使用 startForegroundService() 方法来启动前台服务,而不能使用 startService()。

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
    context.startForegroundService(intent);
} else {
    context.startService(intent);
}
  1. service服务中的Notification

在 API 26 及以上版本,首先需要创建一个 NotificationChannel 对象,并为其设置一些属性(例如声音、震动等)。然后用该 Channel 创建一个 Notification,并调用 startForeground() 方法将其赋给前台服务。这样,即使在设备处于 Doze 策略模式时,该服务仍能保持活动状态。在 API 26 以下版本,直接调用 startService() 方法即可正常启动服务。

值得注意的是,为了满足前台服务的要求,通知必须包含在 Notification 对象中。通知提供了有关服务当前状态和活动实例的信息,以便用户随时可以查看和监视该服务的运行情况。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   // 创建一个 NotificationChannel  
   NotificationChannel channel = new NotificationChannel(channelId,channelName, NotificationManager.IMPORTANCE_DEFAULT); 
   // 自定义设置通知声音、震动等
   channel.enableVibration(true); 
   channel.setVibrationPattern(new long[]{100, 200}); 
   NotificationManager notificationManager = getSystemService(NotificationManager.class); 
   notificationManager.createNotificationChannel(channel);
   // 构建一个 Notification 
   Notification notification = new NotificationCompat.Builder(this, channelId) 
       .setContentTitle("Some Service") 
       .setContentText("服务正在运行...") 
       .setSmallIcon(R.drawable.ic_notification) 
       .build(); 
    // 启动前台服务 
    // 通知栏标识符 前台进程对象唯一SERVICE_ID
    startForeground(SERVICE_ID, notification);
} else {
    startService(intent); // API < 26 直接启动服务即可
}

注意事项

启动一个前台服务要做的事情有:

(1) 调用 ContextCompat.startForegroundService() 可以创建一个前台服务,相当于创建一个后台服务并将它推到前台;

(2) 创建一个用户可见的 Notification ;

(3) 必须在5秒内调用该服务的 startForeground(int id, Notification notification) 方法,否则将停止服务并抛出 android.app.RemoteServiceException:Context.startForegroundService() did not then call Service.startForeground()异常。

  • 如果在 5 秒内没有调用startForeground(),timeout 就会触发,会报出ANR
  • 一旦通过startForegroundService() 启动前台服务,必须在service 中有startForeground() 配套,不然会出现ANR 或者crash
  • startForeground() 中的id 和notification 不能为0 和 null

相关拓展

类别区别应用
前台服务会在通知一栏显示 ONGOING 的 Notification, 当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。常见的如音乐播放服务
后台服务默认的服务即为后台服务,即不会在通知一栏显示 ONGOING 的 Notification。 当服务被终止的时候,用户是看不到效果的。某些不需要运行或终止提示的服务,如天气更新,日期同步,邮件同步等。

startForegroundService()startService() 是 Android 中用于启动服务的两种方法,它们之间的主要区别在于:

  1. API 级别:startForegroundService() 方法是在 Android O (API 级别 26) 引入的,而 startService() 方法则是基于早期版本的 API 设计的。

  2. 后台限制策略:为了避免系统和用户资源被滥用,Android 8.0(API 级别 26)以上版本中增加了一些针对后台服务的限制策略。在这些限制策略下,应用程序必须使用 startForegroundService() 方法来启动前台服务,而不能使用 startService()

  3. 前台通知:startForegroundService() 方法需要与 startForeground() 方法配合使用,以在状态栏中创建前台通知。前台通知可让用户明确知道应用正在执行某些操作,并防止系统将其进程或服务结束或处于 Doze 模式。而 startService() 则不会创建前台通知,因此系统可能会更轻易地终止其进程或服务。

因此,如果您计划启动一个长时间运行的服务或者希望保持服务在设备休眠时仍然运行,可以考虑使用 startForegroundService()startForeground() 方法。如果只是启动一个短暂的服务并且不需要该服务在设备休眠时仍然保持运行,则可以使用 startService() 方法。

需要注意的是,即使您使用了 startForegroundService() 方法,系统也会在必要时终止其进程或服务。因此,在设计应用程序时,应该考虑将服务设计为尽可能少消耗系统资源,并及时释放不必要的资源来避免出现资源过度占用等问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 启动前台服务的实现方法与注意事项 的相关文章

  • ADX的计算方式

    平均趋向指数是衡量趋势的技术工具 xff0c 简称ADX average directional indicator xff0c 它是由韦尔斯 怀尔德在1978年提出 xff0c 与其他技术分析工具不同的是 xff0c ADX并不能判断多空
  • uni app项目中实现vue和html通信

    vue实现 web view 是一个 web 浏览器组件 xff0c 可以用来承载网页的容器 xff0c 会自动铺满整个页面 个人业务 xff08 需要实现一个本地的html文件的内嵌 xff09 xff0c 由于web view是自动铺满
  • uni app实现中英文语言切换

    因为业务需求很多app都是可以多种语言进行切换的 xff0c 以此来方便用户的使用 做语言的切换一定要开发开始的时候就规划好 xff0c 不然确实太麻烦了 xff0c 我是后期开发的语言切换 xff0c 好多个页面都需要进行修改 main
  • uniapp一套代码开发app和微信小程序

    为什么选择uniapp开发 xff1f 为什么选择uniapp进行开发 xff1f 1 uniapp对于独自开发是相当友好的 xff0c 一套代码可以兼容app xff08 安卓 xff0c ios xff09 小程序 xff0c h5等
  • python + selenium的使用 - mac可能出现的问题

    注意服务器部署selenium时 xff0c 代码中一定要添加关闭浏览器驱动的语句 xff08 代码执行结束后不会自动关闭浏览器驱动 xff09 xff0c 否则会导致服务器磁盘被占满 1 安装selenium pip span class
  • 使用Truffle 和 Ganache编译、发布智能合约

    文章目录 Truffle开发框架步骤1 安装Truffle2 查看安装是否成功3 创建没有合约的空工程 xff0c 可以使用 truffle init4 编译Truffle项目的合约truffle compile编译问题 5 构建文件Art
  • 基于Ganache和MetaMask搭建以太坊私有网络

    使用Truffle 和 Ganache 编译 发布智能合约 请参考作者博客https blog csdn net weixin 43958804 article details 109576016 操作步骤 下载ganache https
  • python面试题--统计文件中字母出现的次数

    统计字母出现的次数 fp span class token operator 61 span span class token builtin open span span class token punctuation span span
  • 迁移EFI分区至固态硬盘

    接上回 加装SSD后的第二天 xff0c 我发现原来20s开机的电脑居然变成了30s开机 于是我就开始思考什么问题导致了这个情况 xff0c 根据启动顺序问题 xff0c 我发现可能是安装系统时 xff0c 我没拔下HDD的SATA0接口的
  • go defer,panic,recover详解 go 的异常处理

    转载 https www jianshu com p 63e3d57f285f golang中defer panic recover是很常用的三个特性 xff0c 三者一起使用可以充当其他语言中try catch 的角色 xff0c 而de
  • 重新在虚拟机上安装了centOS7系统

    参考教程 xff1a VMware 安装 Centos7 超详细过程 菜鸟教程
  • centOS安装

    1 安装ImageMagick yum install y ImageMagick 2 安装GhostScript yum install y ghostscript 验证是否安装成功 gs version 3 安装libreoffice
  • 10问10答:你真的了解线程池吗?

    Java开发手册 中强调 xff0c 线程资源必须通过线程池提供 xff0c 而创建线程池必须使用ThreadPoolExecutor 手册主要强调利用线程池避免两个问题 xff0c 一是线程过渡切换 xff0c 二是避免请求过多时造成OO
  • TensorRT 加载模型onnx报错: Error Code 10: Internal Error (Could not find any implementation for node

    1 背景 在TensorRT加载ONNX文件 bert模型 xff09 过程出现如标题所示的错误信息 在相同的代码 xff0c 相同的TensorRT版本 xff0c 在3090 xff08 43 win10 xff09 可以进行正常加载和
  • 【Git】在IDEA拉取master分支到你的开发分支上

    git checkout到master2 git pull xff0c 拉去master最新代码 3 git checkout到你的开发分支 右键项目 选择远程master 确定后如果有冲突 xff0c 则解决冲突即可 弄完最后git pu
  • UNIX环境高级编程-第一章

    1 UNIX体系结构 xff1a 严格意义上说 xff0c 可将操作系统定义为一种软件 xff0c 它控制计算机硬件资源 xff0c 提供程序运行环境 我们通常将这种软件称为内核 xff0c 因为它相对较小 xff0c 而且位于环境的核心
  • AP6275S移植总结

    RK3308B 43 AP6275S移植 在rk3308b平台移植rtl8821cs rlt8821cs是wifi 43 bt一体的模组 xff0c 主要记录下移植过程中需要注意的地方 移植驱动 将rtl8821cs的驱动包复制到rk的SD
  • float类型

    float类型遵循IEEE754标准 xff0c 该标准为32位浮点数规定了二进制表示形式 IEEE754采用二进制的科学计数法来表示浮点数 对于float浮点数 xff0c 用1位表示数字的符号 xff08 浮点数正负性 xff0c 0正
  • 判断点与直线的位置关系

    判断点与直线的位置关系是计算几何里面的一个最基本算法 xff0c 可以使用向量来判断 定义 xff1a 平面上三个点A x1 y1 B x2 y2 C x3 y3 xff0c 判断点C与 A B overr
  • 【知识点总结】大数据技术原理与应用

    大数据技术原理与应用 本文是对 大数据与云计算导论 课程知识点的应试总结 基本涵盖了 大数据技术原理与应用 的重点内容 思维导图由 64 福尔摩东整理 第一章 大数据概述 1 三次信息化浪潮 信息化浪潮发生时间标志解决的问题代表企业第一次浪

随机推荐

  • BlockingQueue

    BlockingQueue 一 阻塞队列基本方法介绍 谈到线程池 xff0c 不得不谈到生产者 消费者模式 xff0c 谈到生产者 消费者 xff0c 就不得不谈到对应的数据结构 xff0c 谈到对应的数据结构不得不言 BlockingQu
  • 【Python爬虫】猫眼电影榜单Top100

    这是一个入门级的Python爬虫 xff0c 结构易于理解 本文对编写此爬虫的全过程进行了讲述 希望对大家的Python爬虫学习有所帮助 一 目标 爬取猫眼电影榜单Top100 xff0c 将数据存入Excel文件中 xff0c 并利用py
  • 【知识点总结】计算机操作系统

    第一章 操作系统引论 操作系统的特征 并发 共享 虚拟 异步 并发和共享是两个最基本的特征 xff0c 二者互为存在条件 1 并发与并行 并发 xff1a 指两个或多个事件在同一时间间隔内发生 这些事件宏观上是同时发生的 xff0c 但微观
  • RD Client 用户账户无效解决办法

    账户密码都正确的情况下 xff0c 在局域网内登录总是显示用户账户无效 查找了微软讨论组 csdn xff0c 使用他们提供的解决办法都未能解决我的问题 xff0c 最终在知乎找见了如下的方法 xff0c 成功连接 打开本地组策略编辑器 计
  • FRP内网穿透 远程桌面的搭建

    一 准备 内容要求操作系统Win10家庭版以上服务器具有公网ip远程软件RD Client 二 软件介绍 1 Win10专业版 企业版 2 RD Client xff08 Microsoft 远程桌面 xff09 主要功能 访问运行Wind
  • 【考研】数据结构复习

    一 线性表 1 线性表的顺序表示 xff08 1 xff09 定义 静态分配 define MaxSize 50 typedef struct ElemType data MaxSize int length SqList void Ini
  • 层板等分衣柜 简单实现

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • 使用spire.doc for java 操作文档(添加段落,动态生成表格,给段落设置字体样式等)

    31 使用spire doc for java 操作文档记录 span class token comment 创建段落 span span class token keyword public span span class token
  • HBuilderX - uniapp - 运行项目到微信开发者工具 - 提示项目下缺少manifest.json文件

    1 有manifest json的情况下报错 xff0c 选中项目 xff0c 右键菜单 xff0c 重新识别项目类型 xff0c 再次运行 参考文档 xff1a HBuilderX 项目根目录下缺少manifest json 峻宇 博客园
  • 图片上传到FTP服务器之后,从ftp服务器下载图片到本地会失真

    问题描述 有一个需求是需要把下载的图片上传到ftp服务器 xff0c 但是当把图片上传完之后 xff0c 下载到本地发现图片失真了 xff0c 如图 xff1a 看了网上很多办法比如 xff1a ftpClient setFileType
  • hisat2 cifflinks

    hisat2 p 8 dta cufflinks x hisat2 data script sh 1 PH 1 1 0h2 1 1 fq gz 2 0h2 1 0h2 1 2 fq gz S 0h2 1 sam
  • centOS7上面安装wkhtmltopdf的记录

    Using username terry Last login Sun Feb 16 21 46 27 2020 from 192 168 31 134 terry 64 MiWiFi R4AC srv su 密码 xff1a root 6
  • 一键清理项目下pycharm和Jupyter缓存文件

    前言 在进行python编程开发时 xff0c Jupyter和Pycharm是两个比较常用的开发工具 pycharm在运行py文件时会生成以 pycache 命名的缓存文件夹 xff0c 而jupyter在打开ipynb时会生成以 ipy
  • Spring框架常考知识点总结

    1 Spring常见的注入方式有 xff1a setter注入和构造注入 2 依赖注入的目标是 xff1a 在代码之外管理程序组建间的依赖关系 3 下面关于IOC的理解 xff0c 正确的是 xff1a 控制反转和对象被动的接受依赖类 4
  • MATLAB GUI图形界面设计一个学生管理系统

    设计一个简单的学生成绩管理程序 xff0c 包含如下功能 xff1a 1 可创建不少于100名学生成员 xff1b 2 每名成员的记录包括 xff1a 学号 姓名 专业和5门课程的成绩 xff1b 3 能够实现添加 删除 修改学生成员 xf
  • Java多线程----消费者/生产者模型

    前言 生产者和消费者问题是线程模型中的经典问题 xff1a 生产者和消费者在同一时间段内共用同一个存储空间 xff0c 生产者往存储空间中添加产品 xff0c 消费者从存储空间中取走产品 xff0c 当存储空间为空时 xff0c 消费者阻塞
  • 操作系统之聊天系统的实现

    实验要求 在linux系统用c c 43 43 语言编写一个多用户的聊天室管理系统 主要功能 xff1a 1 能做到3个以上用户之间的聊天 xff1b 2 系统要有用户管理功能 xff1b 3 每个用户能管理自己的权限 xff0c 比如 不
  • Android系统连接WIFI显示网络连接受限

    问题描述 使用Android设备打开设置 xff0c 选择WIFI输入正确密码连接 xff0c 会显示已连接 xff0c 无网络 xff0c 然后变成网络连接受限 xff0c 实际可以使用此WIFI进行上网 问题分析 异常Log D Net
  • Android View绑定框架——ButterKnife & Viewbinding

    ButterKnife 是一个专注于Android系统的View注入框架 以前总是要写很多findViewById来找到View对象 xff0c 有了ButterKnife可以很轻松的省去这些步骤 最重要的一点 xff0c 使用Butter
  • Android 启动前台服务的实现方法与注意事项

    问题描述 Android R平台 收音机启动前台服务 startForegroundService 报错 span class token class name E span span class token class name Andr