Android中的NotificationManager

本文深入解析了Android系统中NotificationManager的使用方法及其内部工作原理,包括Toast和Notification两种通知方式的具体实现过程。同时介绍了NotificationManagerService如何管理和响应通知,以及与之相关的广播接收器和系统服务交互。
摘要由CSDN通过智能技术生成
转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>

NotificationManager支持Toast和Notification两种通知方式,前者相当于一个定时关闭的对话框,后者是在状态栏上显示一条消息。Toast和Notification都可以随时取消。INotificationManager的接口定义如下:

INotificationManager  

interface INotificationManager
{
    void enqueueNotification(String pkg, int id, in Notification notification, inout int[] idReceived);
    void cancelNotification(String pkg, int id);
    void cancelAllNotifications(String pkg);
 
    void enqueueToast(String pkg, ITransientNotification callback, int duration);
    void cancelToast(String pkg, ITransientNotification callback);
}

Toast  

Toast在show时会自动调用enqueueToast:

    public void show() {
        if (mNextView == null) {
            throw new RuntimeException("setView must have been called");
        }
 
        INotificationManager service = getService();
 
        String pkg = mContext.getPackageName();
 
        TN tn = mTN;
 
        try {
            service.enqueueToast(pkg, tn, mDuration);
        } catch (RemoteException e) {
            // Empty
        }
    }

NotificationManager  

NotificationManager对service的接口做了包装:

获取service,并转换成INotificationManager接口:

    static private INotificationManager getService()
    {
        if (sService != null) {
            return sService;
        }
        IBinder b = ServiceManager.getService("notification");
        sService = INotificationManager.Stub.asInterface(b);
        return sService;
    }

发送notification, 会自动填充一些参数,然后调用enqueueNotification。

    public void notify(int id, Notification notification)
    {
        int[] idOut = new int[1];
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        try {
            service.enqueueNotification(pkg, id, notification, idOut);
            if (id != idOut[0]) {
                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
            }
        } catch (RemoteException e) {
        }
    }

Notification  

Notification主要是存放通知需要的相关数据,比如图标、信息、时间和手机表现方式(如闪烁、声音和震动)以及用户点击之后要打开的URL等。

    /**
     * Constructs a Notification object with the information needed to
     * have a status bar icon without the standard expanded view.
     *
     * @param icon          The resource id of the icon to put in the status bar.
     * @param tickerText    The text that flows by in the status bar when the notification first
     *                      activates.
     * @param when          The time to show in the time field.  In the System.currentTimeMillis
     *                      timebase.
     */
    public Notification(int icon, CharSequence tickerText, long when)
    {
        this.icon = icon;
        this.tickerText = tickerText;
        this.when = when;
    }
    public void setLatestEventInfo(Context context,
            CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
        RemoteViews contentView = new RemoteViews(context.getPackageName(),
                com.android.internal.R.layout.status_bar_latest_event_content);
        if (this.icon != 0) {
            contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
        }
        if (contentTitle != null) {
            contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
        }
        if (contentText != null) {
            contentView.setTextViewText(com.android.internal.R.id.text, contentText);
        }
        if (this.when != 0) {
            Date date = new Date(when);
            CharSequence str =
                DateUtils.isToday(when) ? DateFormat.getTimeFormat(context).format(date)
                    : DateFormat.getDateFormat(context).format(date);
            contentView.setTextViewText(com.android.internal.R.id.time, str);
        }
 
        this.contentView = contentView;
        this.contentIntent = contentIntent;
    }

NotificationManagerService  

NotificationManagerService则是负责实际的Notification管理了。

里面实现了一个BroadcastReceiver,用来监听电池充电状态和软件包管理的事件。

    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
 
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
...
            } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
                    || action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
...
            }
        }
    };

震动调用Vibrator的函数。
播放声音调用AsyncPlayer的函数。
闪光调用HardwareService的函数。
向StatusBarService注册相关事件。
statusBar.setNotificationCallbacks(mNotificationCallbacks);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值