android Foreground Service 前台服务/notification全局通知
前言
我在设计一款自用的用于自我管理的app,为了增强自我反馈,我想要这个软件能够持续的显示我执行某一个事件所用的时间。并且为了使得软件不会被系统自动关闭,百般斟酌后我选了前台服务方案。
要素简介
前台服务(Foreground Service)
前台服务(Foreground Service)相比起后台服务(Service),拥有一个优势那就是在系统内存不足的时候不允许系统杀死的服务,并且在运行时需要能被用户所知,需要在状态栏创建一个通知来管理。
全局通知(notification)
全局通知(notification),常用于告知用户某些事件在某个事件发生,在发动时会在状态栏和通知栏都显示信息,用户可以点击信息进行某些功能的管理
功能实现
声明服务与获取权限
声明权限
<!-- 通知权限 -->
<!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>-->
<!-- 前台权限权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
声明service
<service android:name=".AppService"/>
在最新版本中notification已被启用,改为使用NotificationCompat
案例如下:
Notification 初始化
registerNotificationChannel();
notifyId = 0x975;//(int) System.currentTimeMillis();
Intent nfIntent = new Intent(this, HostActivity.class);
mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
mBuilder.setContentIntent(PendingIntent.
getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
.setContentTitle("下拉列表中的Title") // 设置下拉列表里的标题
.setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
.setContentText("要显示的内容") // 设置上下文内容
.setWhen(System.currentTimeMillis()) // 设置该通知发生的时间
//.setPriority(Notification.PRIORITY_MIN) //设定为最低优先级
.setPriority(Notification.PRIORITY_HIGH) //设定为最高优先级
.setOngoing(true)//设定为点击后不消失
;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
mBuilder.setContentTitle(getResources().getString(R.string.app_name));
}
//notificationManager.notify(notifyId, mBuilder.build());
startForeground(notifyId, mBuilder.build());
- 其中notifyId是通知的唯一标识当通知的notify一致时,再发布通知则会覆盖原有的通知内容。这个方法也常用于实时更新通知内容
- 前台服务发布通知的方法为startForeground,使用方法和notificationManager.notify类似,不需要另外再注册Manager。
NotificationChannel 通知渠道
而在高版本的安卓中,还需要注册通知渠道:
/**
* 注册通知通道
*/
private void registerNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
if (notificationChannel == null) {
NotificationChannel channel =