Android N NotificationManagerService源码分析

关于NotificationManagerService的使用推荐参考下面资料,写的不错:

Android4.4 NotificationManagerService使用详解与原理分析(一)、(二):点击打开链接

这里主要分析framework层的源码。

相关文件主要有:

frameworks\base\core\java\android\app\NotificationManager.java;

frameworks\base\services\core\java\com\android\server\notification\NotificationManagerService.java;

frameworks\base\services\core\java\com\android\server\statusbar\StatusBarManagerService.java;



第三方应用发起通知时,调用的是NotificationManager的notify方法,我们就从这里入手。

notify方法表示发送一个显示在状态栏上的通知,代码如下:

    /**
     * Post a notification to be shown in the status bar. If a notification with
     * the same id has already been posted by your application and has not yet been canceled, it
     * will be replaced by the updated information.
     *
     * @param id An identifier for this notification unique within your
     *        application.
     * @param notification A {@link Notification} object describing what to show the user. Must not
     *        be null.
     */
    public void notify(int id, Notification notification)
    {
        notify(null, id, notification);
    }

如果你的第三方应用发送了一个相同id的通知,并且没有被取消,它将被更新的信息所取代。

    /**
     * Post a notification to be shown in the status bar. If a notification with
     * the same tag and id has already been posted by your application and has not yet been
     * canceled, it will be replaced by the updated information.
     *
     * @param tag A string identifier for this notification.  May be {@code null}.
     * @param id An identifier for this notification.  The pair (tag, id) must be unique
     *        within your application.
     * @param notification A {@link Notification} object describing what to
     *        show the user. Must not be null.
     */
    public void notify(String tag, int id, Notification notification)
    {
        notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
    }
如果你的第三方应用发送了一个相同tag和id的通知,并且没有被取消,它将被更新的信息所取代。

    /**
     * @hide
     */
    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
    {
        int[] idOut = new int[1];
        INotificationManager service = getService();//获取IBinder对象(NotificationManagerService)
        String pkg = mContext.getPackageName();
        // Fix the notification as best we can.
        Notification.addFieldsFromContext(mContext, notification);//"android.appinfo"、"android.originatingUserId"
        if (notification.sound != null) {
            notification.sound = notification.sound.getCanonicalUri();
            if (StrictMode.vmFileUriExposureEnabled()) {
                notification.sound.checkFileUriExposed("Notification.sound");
            }
        }
        fixLegacySmallIcon(notification, pkg);
        if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (notification.getSmallIcon() == null) {
                throw new IllegalArgumentException("Invalid notification (no valid small icon): "
                        + notification);
            }
        }
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
        try {
            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                    copy, idOut, user.getIdentifier());
            if (id != idOut[0]) {
                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
  • 我们看下Notification的addFieldsFromContext方法做了哪些事情:

    /**
     * @hide
     */
    public static void addFieldsFromContext(Context context, Notification notification) {
        addFieldsFromContext(context.getApplicationInfo(), context.getUserId(), notification);
    }

    /**
     * @hide
     */
    public static void addFieldsFromContext(ApplicationInfo ai, int userId,
            Notification notification) {
        notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, ai);//"android.appinfo"
        notification.extras.putInt(EXTRA_ORIGINATING_USERID, userId);//"android.originatingUserId"
    }

主要是保存了当前应用对应的ApplicationInfo对象和对应的userId。在Android4.4中Notification新增了extras字段,用来保存系统通知的一些具体信息,定义如下:

    /**
     * Additional semantic data to be carried around with this Notification.
     * <p>
     * The extras keys defined here are intended to capture the original inputs to {@link Builder}
     * APIs, and are intended to be used by
     * {@link android.service.notification.NotificationListenerService} implementations to extract
     * detailed information from notification objects.
     */
    public Bundle extras = new Bundle();
addFieldsFromContext方法主要实现将当前应用的ApplicationInfo对象保存到“android.appinfo”字段,将当前的userId保存到“android.originatingUserId”字段中。

  • fixLegacySmalIcon,notify函数会判断notification是否有small icon࿰
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值