Android笔记(十六):前台服务

设置服务为前台服务。前台服务会在状态栏显示一个通知。通知界面与服务进行关联。

一、什么是通知?

Notification通知是在移动应用APP提供给用户的消息提示,是在移动系统的通知栏中显示。当移动应用不在运行时或者在后台状态下,通过发布通知给用户,用户可以浏览通知的提示信息或者对通知进行某些操作。

在这里插入图片描述
图1 通知显示示例
如上图所示:
①小图标:为必要图标,通过setSmallIcon()设置
②应用名称:由系统提供。
③时间戳:由系统提供,可以通过setWhen()进行替换或使用setShowWhen(false)将其隐藏。
④标题:可选内容,通过setContentTitle()设置。
⑤文本:可选内容,通过setContentText()设置。
⑥大图标:可选图标(通常仅用于联系人照片),通过setLargeIcon设置。
⑦样式:通过样式设置大图片

1.在AndroidManifest.xml中配置发布通知的权限

注意从Android13开始发布通知需要配置android.permission.POST_NOTIFICATIONS许可

  <!-- 设置发布通知许可 --> <uses-permission    android:name="android.permission.POST_NOTIFICATIONS" />

2.请求发布通知权限

// 请求发布通知权限

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU) {
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),
0)
}

3. 创建通知渠道和创建通知

(1)创建通知渠道

从 Android 8.0(API 级别 26)开始,所有通知都必须分配到相应的渠道。

    //定义通知管理器val notificationManager:NotificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager//定义通知渠道的标识val channelId = "com.example.ch07"//定义通知渠道的名称val channelName = "移动应用开发"//定义通知渠道:指定通知渠道的标识、名称和通知渠道的重要级别val channel = NotificationChannel(channelId,channelName, NotificationManager.IMPORTANCE_DEFAULT)//定义通知渠道的描述信息val channelDesc = "移动应用通知渠道描述"//创建并配置通知渠道notificationManager.createNotificationChannel(channel)

(2)创建通知

    //创建通知val notification = Notification.Builder(this,channelId) .apply{//设置通知标题setContentTitle("通知实例一")//设置通知内容setContentText("欢迎使用通知")//设置通知时间setWhen(System.currentTimeMillis())//设置通知的小图标setSmallIcon(R.mipmap.nature)//设置通知的大图标setLargeIcon(BitmapFactory.decodeResource(resources,R.mipmap.someone))//设置通知样式style = Notification.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.mipmap.honggutan))}.build()

(3)发布通知

    //创建通知标记val notificationID = 1//发布通知到通知栏notificationManager.notify(notificationID,notification)

4. 通知实例

接下来通过实例来说明发布通知:

(1)定义界面MainScreen

在MainScreen中定义发布通知的按钮,提供交互处理

@Composable
fun MainScreen(postAction:()->Unit){Box(modifier = Modifier.fillMaxSize(),contentAlignment = Alignment.Center){TextButton(onClick={postAction.invoke()}){Text("发布通知",fontSize = 24.sp)}}
}

(2)定义主活动MainActivity

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)//请求权限requestNotificationPermission()setContent {Ch07_DemoTheme {Surface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {MainScreen {showNotification()}}}}}private fun requestNotificationPermission(){// 检查通知权限是否已经授予 注意:API 33以上版本需要检查POST_NOTIFICATIONS发布通知权限if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.TIRAMISU) {ActivityCompat.requestPermissions(this,arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),0)}}private fun showNotification(){//定义通知管理器val notificationManager:NotificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager//定义通知渠道的标识val channelId = "com.example.ch07"//定义通知渠道的名称val channelName = "移动应用开发"//定义通知渠道:指定通知渠道的标识、名称和通知渠道的重要级别val channel = NotificationChannel(channelId,channelName, NotificationManager.IMPORTANCE_DEFAULT)//定义通知渠道的描述信息val channelDesc = "移动应用开发通知渠道描述"//创建并配置通知渠道notificationManager.createNotificationChannel(channel)//创建通知val notification =Notification.Builder(this,channelId).apply{//设置通知标题setContentTitle("通知实例一")//设置通知内容setContentText("欢迎使用通知")//设置通知时间setWhen(System.currentTimeMillis())//设置通知的小图标setSmallIcon(R.mipmap.nature)//设置通知的大图标setLargeIcon(BitmapFactory.decodeResource(resources,R.mipmap.someone))//设置通知样式style =Notification.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.mipmap.honggutan))}.build()//创建通知标记val notificationID = 1//发布通知到通知栏,注意从Android13开始发布通知需要配置android.permission.POST_NOTIFICATIONS许可notificationManager.notify(notificationID,notification)}
}

运行结果如下所示:

在这里插入图片描述

图2 运行结果
运行结果的图片来自网络,如有侵权,告知,会主动删除。

二、前台服务

设置服务为前台服务。前台服务会在状态栏显示一个通知。通知界面与服务进行关联。从Android 14版本(API Level 34)开始,每个前台服务需要声明合适的服务类型。也就是在启动前台服务时,系统会根据服务类型检查是否满足前提条件。
表2-1 常见服务类型

前台服务类型要声明的权限运行时要求前提条件运行时请求权限请求权限调用的方法说明
相机FOREGROUND_SERVICE_CAMERA请求CAMERA运行时权限在后台访问相机
连接设备FOREGROUND_SERVICE_CONNECTED_DEVICECHANGE_NETWORK_STATE或CHANGE_WIFI_STATE或CHANGE_WIFI_MULTICAST_STATE或NFC或TRANSMIT_IRBLUETOOTH_CONNECT或BLUETOOTH_ADVERTISE或BLUETOOTH_SCAN或UWEB_RANGING调用UsbManager.requestPermission()与需要的蓝牙、NFC、IR、USB或网络的外部设备互动
数据同步FOREGROUND_SERVICE_DATA_SYNC数据传输的操作
健康FOREGROUND_SERVICE_HEALTHHIGH_SAMPLING_RATE_SENSORSBORY_SENSORS或ACTIVITY_RECOGNITION为健身类别的应用提供支持
位置FOREGROUND_SERVICE_LOCATIONACESS__COARSE_LOCATION或ACESS_FINE_LOCATION为位置信息使用权的长时间运行用例
媒体FOREGROUND_SERVICE_MEDIA_PLAYBACK在后台继续播放音频或视频
媒体投影FOREGROUND_SERVICE_MEDIA_PROJECTION调用createScreenCaptureIntent()使用MediaProjection API将内容投影到外部
麦克风FOREGROUND_SERVICE_MICROPHONERECORD_AUDIO在后台继续捕获麦克风内容
致电FOREGROUND_SERVICE_PHONE_CALLMANAGE_OWN_CALLS使用COnnetionService API继续当前通话
远程消息传递FOREGROUND_SERVICE_REMOTE_MESSAGING将短信从一台设备转移另外一台设备
配置前台服务

启动前台服务

Context.startForeground(int,Notification)

例:创建一个前台服务,播放mp3文件,并在状态栏中显示相应的通知。

1.创建服务

在这里插入图片描述
自定义服务,可以控制音频的播放,代码如下:

class MusicService : Service() {lateinit var mediaPlayer: MediaPlayeroverride fun onCreate() {super.onCreate()mediaPlayer = MediaPlayer.create(this,R.raw.song3)}override fun onBind(intent: Intent): IBinder? {postNotification()mediaPlayer.setOnPreparedListener {mediaPlayer.start()}mediaPlayer.setOnCompletionListener {mediaPlayer.stop()}return null}override fun onUnbind(intent: Intent?): Boolean {if(mediaPlayer.isPlaying) {mediaPlayer.stop()}return super.onUnbind(intent)}/*** Request notification permission* 请求通知权限*/private fun requestNotificationPermission(){val notificationPermissionGranted =NotificationManagerCompat.from(this).areNotificationsEnabled()if(!notificationPermissionGranted){val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)intent.putExtra(Settings.EXTRA_APP_PACKAGE,packageName)startActivity(intent)}}private fun postNotification(){//请求通知权限requestNotificationPermission()//创建通知管理器val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager//定义通知渠道val channel = NotificationChannel("music_service","一剪梅",NotificationManager.IMPORTANCE_DEFAULT)//创建通知渠道notificationManager.createNotificationChannel(channel)//定义启动服务的意图val intent1 = Intent(this,NextActivity::class.java)//定义悬浮意图val pendingIntent = PendingIntent.getActivity(this,0,intent1,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)//创建通知val notification = NotificationCompat.Builder(this,"music_service").apply{setOngoing(true)setOnlyAlertOnce(true)setContentTitle("播放音乐")setContentText("正在歌曲播放一剪梅...")setSmallIcon(R.mipmap.ic_launcher)setColorized(true)color = resources.getColor(R.color.teal_200,null)setContentIntent(pendingIntent)}.build()startForeground(1,notification)}
}

2.在AndroidManifest.xml配置服务

<serviceandroid:foregroundServiceType="mediaPlayback"android:name=".MusicService"android:enabled="true"android:exported="true" />

设置前台服务类型为mediaPlayback

3.在自定义应用中创建通知渠道

class MusicApp: Application() {override fun onCreate() {super.onCreate()//从API 26开始使用通知渠道if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){//定义通知管理器val notificationManager: NotificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager//定义通知渠道的标识val channelId = "com.example.course.ch07"//定义通知渠道的名称val channelName = "移动应用开发"//定义通知渠道:指定通知渠道的标识、名称和通知渠道的重要级别val channel = NotificationChannel(channelId,channelName,NotificationManager.IMPORTANCE_DEFAULT)//创建并配置通知渠道notificationManager.createNotificationChannel(channel)}}
}

需要在AndroidManifest.xml中指定自定义的应用为当前应用,配置自定义应用

     <applicationandroid:name=".MusicApp" ...>.......</application>

4. 在主活动MainActivity中启动服务

要启动前台服务需要在AndroidManifest.xml配置前台服务的权限:

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

在主活动启动前台服务

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val intent1 = Intent(this,MusicService::class.java)requestPermissions()setContent {Ch07_DemoTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally){Row{TextButton(onClick = {startService(intent1)}){Text("播放",fontSize = 20.sp)}TextButton(onClick = {stopService(intent1)}){Text("停止",fontSize = 20.sp)}}}}}}}private fun requestPermissions(){//从API 33开始请求发布通知权限if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU) {ActivityCompat.requestPermissions(this,arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),0)}}
}

在这里插入图片描述
图3

参考文献

  1. 陈轶 《Android移动应用开发(微课版)》清华大学出版社 2022-9 P203-P238

  2. 前台服务启动限制
    https://developer.android.google.cn/about/versions/12/foreground-services?hl=zh-cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/185293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据挖掘实战-基于word2vec的短文本情感分析(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

易点易动固定资产管理系统:提升企业固定资产管理效率的利器

固定资产是企业运营中重要的组成部分&#xff0c;对于企业的正常运转和发展至关重要。然而&#xff0c;传统的固定资产管理方法通常存在效率低下、信息不透明等问题。为了解决这些挑战&#xff0c;易点易动固定资产管理系统应运而生。本文将探讨易点易动固定资产管理系统的概念…

9款高效绘图神器,提升你的工作效率

在日常工作或生活中&#xff0c;我们必须绘制各种图表、流程图、思维导图等图形&#xff0c;或者想用画笔描述自己的想法。然而&#xff0c;我们在许多绘图软件面前感到困惑。我们不知道哪个绘图软件好&#xff0c;也没有足够的时间一一尝试 在接下来的空间里&#xff0c;我们…

堆栈_有效括号

题比较特殊&#xff0c;主要在于它的所有要输入&#xff0c;都是左括号开头&#xff0c;没有右括号开头的&#xff0c;比如"] ["&#xff0c;这种是不算为括号的&#xff0c;由于必然是对称的&#xff0c;若能符合&#xff0c;因而直接在遇到右括号时&#xff0c;检查…

基于python实现心血管疾病风险预测分析

一、项目简介 项目背景 利用心血管疾病风险预测数据集进行深入分析&#xff0c;探究不同因素与心血管疾病风险之间的关联。 数据源 Kaggle上的心血管疾病风险预测数据集。&#xff08;Cardiovascular Diseases Risk Prediction Dataset | Kaggle&#xff09; 二、数据预处…

视图层、模板(补充)

视图层 响应对象 响应---》本质都是 HttpResponse HttpResponse---》字符串render----》放个模板---》模板渲染是在后端完成 js代码是在客户端浏览器里执行的模板语法是在后端执行的redirect----》重定向 字符串参数不是是空的状态码是 3开头JsonResponse---》json格式数据 …

Moonbeam生态项目分析 — — DeFi借贷协议Moonwell

流动性激励计划Moonbeam Ignite是帮助用户轻松愉快体验Moonbeam生态的趣味活动。在Moonbeam跨链连接的推动下&#xff0c;DeFi的各种可能性在这里爆发。DeFi或许不热门&#xff0c;但总有机会捡漏&#xff0c;了解Monbeam生态项目&#xff0c;我们邀请Moonbeam大使分享他们的研…

【linux防火墙】设置开启路由转发,SNAT和DNAT转换原理及应用实操,添加自定义链归类iptables规则

目录 一、关于iptables规则的保存 1.1持久保存规则 1.2加载规则 1.3开机自动加载规则 1.4使用iptables-service软件来进行规则的保存和加载&#xff08;不建议使用&#xff09; 二、SNAT和DNAT的原理和应用 SNAT的原理与应用&#xff1a; DNAT的原理和应用&#xff1a; …

在java java.util.Date 已知逝去时间怎么求年月日 数学计算不用其他方法

在Java中&#xff0c;使用java.util.Date类已知逝去时间求年月日的方法如下&#xff1a; 首先&#xff0c;获取当前时间和逝去时间之间的毫秒数差值&#xff0c;可以使用Date类的getTime()方法获得时间戳。 将毫秒数转换为秒数&#xff0c;并计算出总共的天数。 根据总共的天…

应用软件快速开发平台,一起实现办公流程化发展!

做好办公流程化发展能给企业带来什么好处&#xff1f;其实&#xff0c;在快节奏发展社会中&#xff0c;很多企业的规模和业务量也在不断扩展中&#xff0c;如果还是懒散的办公方式是不能达到事半功倍的效果的。要想实现高效率发展&#xff0c;采用办公流程化发展能让企业管理朝…

【广州华锐互动】节约用水VR互动教育:身临其境体验水资源的珍贵!

随着技术的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在许多领域得到了广泛应用。在节水宣传教育方面&#xff0c;VR技术也展现出了其独特的优势。与传统宣传教育方式相比&#xff0c;节约用水VR互动教育具有更加沉浸式、互动性和实践性的特点&#xff0c;能…

【全栈开发】Next.js与RedwoodJS——比较js框架

Next.js和RedwoodJS是两个广泛用于构建web应用程序的JavaScript框架。这两个框架都提供了一系列功能和好处&#xff0c;但它们在方法和理念上有所不同。在本文中&#xff0c;我们将仔细研究Next.js和RedwoodJS&#xff0c;并对它们进行比较&#xff0c;以帮助您为项目选择正确的…

java开发之基于个微群聊二次开发

请求URL&#xff1a; http://域名地址/getGroupQrCode 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是String登录实例标识chatRoomI…

强化学习-DQN

网上看来很多&#xff0c;但是还是觉得这篇文章将得最好&#xff1a; 可视化强化学习解释 - Deep Q Networks&#xff0c;循序渐进 |Ketan Doshi 博客 (ketanhdoshi.github.io)

泛域名SSL证书是什么?泛域名SSL证书价格多少钱?

泛域名SSL证书是一种SSL证书类型&#xff0c;也被称为通配符SSL证书。SSL证书是保护网站数据传输安全及服务器身份可信的数字证书产品&#xff0c;通常绑定域名或IP&#xff0c;配置到网站服务器上。SSL证书根据保护域名数量及域名类型的不同&#xff0c;可以分为单域名SSL证书…

CentOS7.5搭建Hadoop-3.3.6集群的详细操作流程-实操版本

一、准备工作 1、安装 VMware&#xff0c;已安装的&#xff0c;跳过此步骤即可 官方正版VMware下载&#xff08;16 pro&#xff09;&#xff1a;https://www.aliyundrive.com/s/wF66w8kW9ac 安装&#xff1a;选一下安装地址&#xff0c;一直下一步即可。&#xff08;可能会要…

(免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐

摘 要 随着时代的不断更新&#xff0c;社会的不断变换&#xff0c;信息技术的飞速发展&#xff0c;计算机科技技术也逐步走向成熟。图书馆管理系统对于当今社会来说是必不可少的一个信息组成部分&#xff0c;它可以管理大量图书、大量读者、让读者有条不紊的进行借阅图书&#…

Sui受邀参加Builder DAO举办的LeadUp The Night活动,畅谈Sui与Move语言

LeadUp the Night是一个定期举办的MeetUp活动&#xff0c;由Builder DAO邀请区块链各方项目开发者、VC担任本活动的讲师。这个活动旨在促进区块链技术的发展和应用&#xff0c;让参与者有机会开发创新的区块链应用&#xff0c;探索区块链技术的潜力。 ​​11月30日受BuilderDA…

豆粕期权 MVIX 指数构建及策略回测

1. VIX指数 VIX 最初被设计出来的目的是为了预警市场的潜在风险&#xff0c;一般来说&#xff0c;当 VIX 指数小于 15 时&#xff0c;表示市场出现非理性繁荣&#xff1b;当 VIX 指数大于 40 时&#xff0c;表示市场对 未来的非理性恐慌&#xff0c;短期内可以出现反弹。VIX 指…

leetcode面试经典150题——34 有效的数独(矩阵)

题目&#xff1a; 有效的数独 描述&#xff1a; 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出…