Android O---适配NotificationChannel

本文详细分析了Android O中新增的NotificationChannel,包括其创建、管理及重要性。由于Android 8.0开始强制使用NotificationChannel,开发者需要确保在创建通知时指定渠道ID,否则可能导致应用崩溃。同时,用户可以控制通知渠道的设置,如关闭或更改重要等级,开发者需考虑相应处理逻辑。
摘要由CSDN通过智能技术生成

2018-12-27

继之前跪在Android N的StrictMode上了。现在又跪在的Android O 的NotificationChannel上了

场景如下:

某些场景中需要上传图片,选择图片或者拍照时使用系统的图库会将自己的app置于后台,若选择图片的时间过长,则可能会导致自己的app会杀死。看了一下传承下来的代码,是在这种情况下发送一个前台通知startForeground,使此服务在前台运行。但是会在通知栏上显示一个应用正在运行的通知.

源码分析

查看Android 28的源码,发现调用链如下:

首先 Service.java中调用

 public final void startForeground(int id, Notification notification) {
   
        try {
   
            mActivityManager.setServiceForeground(
                    new ComponentName(this, mClassName), mToken, id,
                    notification, 0);
        } catch (RemoteException ex) {
   
        }
    }

这里的mActivityManager的声明是private IActivityManager mActivityManager = null;在这里,IActivityManager的实现类是ActivityManagerService

@Override
    public void setServiceForeground(ComponentName className, IBinder token,
            int id, Notification notification, int flags) {
   
        synchronized(this) {
   
            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
        }
    }
 public void setServiceForegroundLocked(ComponentName className, IBinder token,
            int id, Notification notification, int flags) {
   
        final int userId = UserHandle.getCallingUserId();
        final long origId = Binder.clearCallingIdentity();
        try {
   
            ServiceRecord r = findServiceLocked(className, token, userId);
            if (r != null) {
   
                setServiceForegroundInnerLocked(r, id, notification, flags);
            }
        } finally {
   
            Binder.restoreCallingIdentity(origId);
        }
    }

finally中调用的Binder方法是一个native方法,主要看一下setServiceForegroundInnerLocked:

方法太长,关注一下我们需要的

                // Apps under strict background restrictions simply don't get to have foreground
                // services, so now that we've enforced the startForegroundService() contract
                // we only do the machinery of making the service foreground when the app
                // is not restricted.
                if (!ignoreForeground) {
   
                    if (r.foregroundId != id) {
   
                        cancelForegroundNotificationLocked(r);
                        r.foregroundId = id;
                    }
                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
                    r.foregroundNoti = notification;
                    if (!r.isForeground) {
   
                        final ServiceMap smap = getServiceMapLocked(r.userId);
                        if (smap != null) {
   
                            ActiveForegroundApp active = smap.mActiveForegroundApps.get(r.packageName);
                            if (active == null) {
   
                                active = new ActiveForegroundApp();
                                active.mPackageName = r.packageName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值