在上一篇文章中,用到了Notification,准备好好的看下notification的源码。

类概述:

一个表示如何使用NotificationManager把一个持久的通知呈现给用户的类。

TheNotification.Builderhas been added to make it easier to construct Notifications.

添加Notification.Builder使构建Notification更容易。

静态变量:

  /**     * Use all default values (where applicable).     */    public static final int DEFAULT_ALL = ~0;        /**     * Use the default notification sound. This will ignore any given     * {@link #sound}.     *      * @see #defaults     */     public static final int DEFAULT_SOUND = 1;    /**     * Use the default notification vibrate. This will ignore any given     * {@link #vibrate}. Using phone vibration requires the      * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.     *      * @see #defaults     */     public static final int DEFAULT_VIBRATE = 2;        /**     * Use the default notification lights. This will ignore the     * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or     * {@link #ledOnMS}.     *      * @see #defaults     */     public static final int DEFAULT_LIGHTS = 4;

定义了默认的灯、震动、声音和全部属性。震动的话需要添加 android.permission.VIBRATE权限。

/**     * Use this constant as the value for audioStreamType to request that     * the default stream type for notifications be used.  Currently the     * default stream type is STREAM_RING.     */    public static final int STREAM_DEFAULT = -1;

notification默认的音频类型。

    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be     * set if you want the LED on for this notification.     * <ul>     * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB     *      or 0 for both ledOnMS and ledOffMS.</li>     * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>     * <li>To flash the LED, pass the number of milliseconds that it should     *      be on and off to ledOnMS and ledOffMS.</li>     * </ul>     * <p>     * Since hardware varies, you are not guaranteed that any of the values     * you pass are honored exactly.  Use the system defaults (TODO) if possible     * because they will be set to values that work on any given hardware.     * <p>     * The alpha channel must be set for forward compatibility.     *      */    public static final int FLAG_SHOW_LIGHTS        = 0x00000001;    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be     * set if this notification is in reference to something that is ongoing,     * like a phone call.  It should not be set if this notification is in     * reference to something that happened at a particular point in time,     * like a missed phone call.     */    public static final int FLAG_ONGOING_EVENT      = 0x00000002;    /**     * Bit to be bitwise-ored into the {@link #flags} field that if set,     * the audio will be repeated until the notification is     * cancelled or the notification window is opened.     */    public static final int FLAG_INSISTENT          = 0x00000004;    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be     * set if you want the sound and/or vibration play each time the     * notification is sent, even if it has not been canceled before that.     */    public static final int FLAG_ONLY_ALERT_ONCE    = 0x00000008;    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be     * set if the notification should be canceled when it is clicked by the     * user.  On tablets, the      */    public static final int FLAG_AUTO_CANCEL        = 0x00000010;    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be     * set if the notification should not be canceled when the user clicks     * the Clear all button.     */    public static final int FLAG_NO_CLEAR           = 0x00000020;    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be     * set if this notification represents a currently running service.  This     * will normally be set for you by {@link Service#startForeground}.     */    public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;    /**     * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification     * represents a high-priority event that may be shown to the user even if notifications are     * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used     * in conjunction with {@link #fullScreenIntent}.     */    public static final int FLAG_HIGH_PRIORITY = 0x00000080;

  • FLAG_SHOW_LIGHTS:
如果想为Notification添加LED灯提示,需要在Flag属性中添加FLAG_SHOW_LIGHT标志位。 LED关闭状态下,0表示颜色或者LED灯开关 LED开启状态下,1代表LED开,0代表LED关。 LED闪烁状态下,ledOnMS表示灯亮时间,ledOffMS表示灯灭时间。 因为硬件不一,所以不能保证在各种硬件上都能够奏效,应尽可能使用系统给定的默认值(TODO),它能够适配各种硬件。 alpha通道必须设置为向前兼容性
  • FLAG_ONGOING_EVENT:
如果需要notification常驻状态栏,引用正在进行的活动,如一个打进的电话,需要在Flag属性中添加FLAG_ONGOING_EVENT标志位。但是其不能引用一个过去已经发生的活动,如一个未接电话。(设置其Flag,notification将被放入“正在进行”组)
  • FLAG_INSISTENT:
设置此Flag,在通知取消或通知窗口打开之前,音频会一直重复。
  • FLAG_ONLY_ALERT_ONCE
设置此Flag,震动和声音只执行一次。
  • FLAG_AUTO_CANCEL:
设置此Flag,当用户点击时,通知会被清除。
  • FLAG_NO_CLEAR
设置此Flag,当用户点击清除所有按钮时,该通知不被清除。
  • FLAG_FOREGROUND_SERVICE
设置此Flag,表示该通知为正运行的服务(当你退出手机QQ时,在状态栏会看到一个QQ图标)
  • FLAG_HIGH_PRIORITY
一个过时的Flag,现在已使用优先级字段代替。设置该Flag表示一高优先级事件,当通知不可以使用(状态栏被隐藏时)也可通知用户,应配合fullScreenIntent使用。

常量

    /**     * The timestamp for the notification.  The icons and expanded views     * are sorted by this key.     */    public long when;    /**     * The resource id of a drawable to use as the icon in the status bar.     * This is required; notifications with an invalid icon resource will not be shown.     */    public int icon;    /**     * If the icon in the status bar is to have more than one level, you can set this.  Otherwise,     * leave it at its default value of 0.     *     * @see android.widget.ImageView#setImageLevel     * @see android.graphics.drawable#setLevel     */    public int iconLevel;    /**     * The number of events that this notification represents.  For example, in a new mail     * notification, this could be the number of unread messages.  This number is superimposed over     * the icon in the status bar.  If the number is 0 or negative, it is not shown in the status     * bar.     */    public int number;    /**     * The intent to execute when the expanded status entry is clicked.  If     * this is an activity, it must include the     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires     * that you take care of task management as described in the     * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back     * Stack</a> document.  In particular, make sure to read the notification section     * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling     * Notifications</a> for the correct ways to launch an application from a     * notification.     */    public PendingIntent contentIntent;    /**     * The intent to execute when the status entry is deleted by the user     * with the "Clear All Notifications" button. This probably shouldn't     * be launching an activity since several of those will be sent at the     * same time.     */    public PendingIntent deleteIntent;    /**     * An intent to launch instead of posting the notification to the status bar.     *     * @see Notification.Builder#setFullScreenIntent     */    public PendingIntent fullScreenIntent;    /**     * Text to scroll across the screen when this item is added to     * the status bar on large and smaller devices.     *     * <p>This field is provided separately from the other ticker fields     * both for compatibility and to allow an application to choose different     * text for when the text scrolls in and when it is displayed all at once     * in conjunction with one or more icons.     *     * @see #tickerView     */    public CharSequence tickerText;    /**     * The view to show as the ticker in the status bar when the notification     * is posted.     */    public RemoteViews tickerView;    /**     * The view that will represent this notification in the expanded status bar.     */    public RemoteViews contentView;    /**     * The bitmap that may escape the bounds of the panel and bar.     */    public Bitmap largeIcon;    /**     * The sound to play.     *      * <p>     * To play the default notification sound, see {@link #defaults}.      * </p>     */    public Uri sound;

  • when:
通知的时间戳,通知图标会根据该时间戳在状态栏进行排序。
  • icon:
在状态栏中显示的图标,如果是无效资源,不予显示。
  • iconLevel:
如果状态栏中的icon有等级之分,可以设置此参数,默认情况下,一般为0.
  • number:
通知事件发生的次数,比如一个邮件通知,这个参数表示未读邮件数。这个数字会叠加到状态栏中通知图标上,如果为0或者负,则不显示。
  • contentIntent:
The intent to execute when the expanded status entry is clicked.当扩展状态内容被点击时触发该intent(expanded status entry不知道该如何翻译是好了)如果是要跳转到一个Activity,一定要包含FLAG_ACTIVITY_NEW_TASK这个标志位,用于调整堆栈中的Task。能够确保正确的从一个通知进入一个应用。
  • deleteIntent:
当用户点击“clean all button"或者滑动取消通知时触发该Intent,不能启动一个activity或者server(因为会在同一时间发送)。
  • fullScreenIntent:
全屏状态下代替状态栏中intent功能
  • tickerText:
当通知发送时像股票一样提示文本。
  • contentView:
在状态栏中代表Notification的View。
  • largeIcon:
可以脱离状态栏的图片
  • sound:
通知声音
  • audioStreamType:
视频播放流类型
  • vibrate:
震动类型
  • ledARGB:
LED灯颜色
  • ledOnMS:
LED灯闪烁时,灯亮时间。
  • ledOffMS:
LED灯闪烁时,灯灭时间。
  • defaults:
LED默认值。

构造函数

默认构造函数:
    /**     * Constructs a Notification object with everything set to 0.     * You might want to consider using {@link Builder} instead.     */    public Notification()    {        this.when = System.currentTimeMillis();    }

可以用Notification.Builder来替代构造一个Notification(关于Builder建造者模式http://blog.csdn.net/aomandeshangxiao/article/details/8214646)。
/**     * @hide     */    public Notification(Context context, int icon, CharSequence tickerText, long when,            CharSequence contentTitle, CharSequence contentText, Intent contentIntent)    {        this.when = when;        this.icon = icon;        this.tickerText = tickerText;        setLatestEventInfo(context, contentTitle, contentText,                PendingIntent.getActivity(context, 0, contentIntent, 0));    }

这个构造函数被hide,setLatestEventInfo方法也被deprecate,不建议使用,使用Notification.Builder即可。
 /**     * 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.     *     * @deprecated Use {@link Builder} instead.     */    @Deprecated    public Notification(int icon, CharSequence tickerText, long when)    {        this.icon = icon;        this.tickerText = tickerText;        this.when = when;    }

这个构造函数是deprecated(弃用)的。
 /**     * Unflatten the notification from a parcel.     */    public Notification(Parcel parcel)    {        int version = parcel.readInt();        when = parcel.readLong();        icon = parcel.readInt();        number = parcel.readInt();        if (parcel.readInt() != 0) {            contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);        }        if (parcel.readInt() != 0) {            deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);        }        if (parcel.readInt() != 0) {            tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);        }        if (parcel.readInt() != 0) {            tickerView = RemoteViews.CREATOR.createFromParcel(parcel);        }        if (parcel.readInt() != 0) {            contentView = RemoteViews.CREATOR.createFromParcel(parcel);        }        if (parcel.readInt() != 0) {            largeIcon = Bitmap.CREATOR.createFromParcel(parcel);        }        defaults = parcel.readInt();        flags = parcel.readInt();        if (parcel.readInt() != 0) {            sound = Uri.CREATOR.createFromParcel(parcel);        }        audioStreamType = parcel.readInt();        vibrate = parcel.createLongArray();        ledARGB = parcel.readInt();        ledOnMS = parcel.readInt();        ledOffMS = parcel.readInt();        iconLevel = parcel.readInt();        if (parcel.readInt() != 0) {            fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);        }    }

通过一个Parcel参数来构造一个Notification。

其他方法

    @Override    public Notification clone() {        Notification that = new Notification();        that.when = this.when;        that.icon = this.icon;        that.number = this.number;        // PendingIntents are global, so there's no reason (or way) to clone them.        that.contentIntent = this.contentIntent;        that.deleteIntent = this.deleteIntent;        that.fullScreenIntent = this.fullScreenIntent;        if (this.tickerText != null) {            that.tickerText = this.tickerText.toString();        }        if (this.tickerView != null) {            that.tickerView = this.tickerView.clone();        }        if (this.contentView != null) {            that.contentView = this.contentView.clone();        }        if (this.largeIcon != null) {            that.largeIcon = Bitmap.createBitmap(this.largeIcon);        }        that.iconLevel = this.iconLevel;        that.sound = this.sound; // android.net.Uri is immutable        that.audioStreamType = this.audioStreamType;        final long[] vibrate = this.vibrate;        if (vibrate != null) {            final int N = vibrate.length;            final long[] vib = that.vibrate = new long[N];            System.arraycopy(vibrate, 0, vib, 0, N);        }        that.ledARGB = this.ledARGB;        that.ledOnMS = this.ledOnMS;        that.ledOffMS = this.ledOffMS;        that.defaults = this.defaults;                that.flags = this.flags;        return that;    }

官网解释:
Creates and returns a copy of this Object. The default implementation returns a so-called "shallow" copy: It creates a new instance of the same class and then copies the field values (including object references) from this instance to the new instance. A "deep" copy, in contrast, would also recursively clone nested objects. A subclass that needs to implement this kind of cloning should call super.clone() to create the new instance and then create deep copies of the nested, mutable objects.

创建并返回这个对象的一个拷贝。默认的实现返回一个所谓的“浅“复制:它创建一个新的实例相同的类,然后从这个实例复制字段值(包括对象引用)生成新实例。相对应的“深度”拷贝,也会递归地复制嵌套对象。一个子类,实现这种克隆需要调用super.clone()方法来创建一个深层嵌套的、可变的实例。
public int describeContents() {        return 0;    }

描述了在Parcelable中包含的各种特殊对象的编组表示。在代码中直接返回0。
 /**     * Flatten this notification from a parcel.     */    public void writeToParcel(Parcel parcel, int flags)    {        parcel.writeInt(1);        parcel.writeLong(when);        parcel.writeInt(icon);        parcel.writeInt(number);        if (contentIntent != null) {            parcel.writeInt(1);            contentIntent.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }        if (deleteIntent != null) {            parcel.writeInt(1);            deleteIntent.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }        if (tickerText != null) {            parcel.writeInt(1);            TextUtils.writeToParcel(tickerText, parcel, flags);        } else {            parcel.writeInt(0);        }        if (tickerView != null) {            parcel.writeInt(1);            tickerView.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }        if (contentView != null) {            parcel.writeInt(1);            contentView.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }        if (largeIcon != null) {            parcel.writeInt(1);            largeIcon.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }        parcel.writeInt(defaults);        parcel.writeInt(this.flags);        if (sound != null) {            parcel.writeInt(1);            sound.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }        parcel.writeInt(audioStreamType);        parcel.writeLongArray(vibrate);        parcel.writeInt(ledARGB);        parcel.writeInt(ledOnMS);        parcel.writeInt(ledOffMS);        parcel.writeInt(iconLevel);        if (fullScreenIntent != null) {            parcel.writeInt(1);            fullScreenIntent.writeToParcel(parcel, 0);        } else {            parcel.writeInt(0);        }    }
用Notification填充Parcel。
  /**     * Parcelable.Creator that instantiates Notification objects     */    public static final Parcelable.Creator<Notification> CREATOR            = new Parcelable.Creator<Notification>()    {        public Notification createFromParcel(Parcel parcel)        {            return new Notification(parcel);        }        public Notification[] newArray(int size)        {            return new Notification[size];        }    };

通过Parcelable.Creator来实例化Notification。
/**     * Sets the {@link #contentView} field to be a view with the standard "Latest Event"     * layout.     *     * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields     * in the view.</p>     * @param context       The context for your application / activity.     * @param contentTitle The title that goes in the expanded entry.     * @param contentText  The text that goes in the expanded entry.     * @param contentIntent The intent to launch when the user clicks the expanded notification.     * If this is an activity, it must include the     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires     * that you take care of task management as described in the     * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back     * Stack</a> document.     *      * @deprecated Use {@link Builder} instead.     */    @Deprecated    public void setLatestEventInfo(Context context,            CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {        RemoteViews contentView = new RemoteViews(context.getPackageName(),                R.layout.status_bar_latest_event_content);        if (this.icon != 0) {            contentView.setImageViewResource(R.id.icon, this.icon);        }        if (contentTitle != null) {            contentView.setTextViewText(R.id.title, contentTitle);        }        if (contentText != null) {            contentView.setTextViewText(R.id.text, contentText);        }        if (this.when != 0) {            contentView.setLong(R.id.time, "setTime", when);        }        this.contentView = contentView;        this.contentIntent = contentIntent;    }

上面提到的setLatestEventInfo方法,被弃用,使用Notification.Builder替代。 设置最新点击的内容视图,通过设置图标,时间等参数。
@Override    public String toString() {        StringBuilder sb = new StringBuilder();        sb.append("Notification(contentView=");        if (contentView != null) {            sb.append(contentView.getPackage());            sb.append("/0x");            sb.append(Integer.toHexString(contentView.getLayoutId()));        } else {            sb.append("null");        }        sb.append(" vibrate=");        if (this.vibrate != null) {            int N = this.vibrate.length-1;            sb.append("[");            for (int i=0; i<N; i++) {                sb.append(this.vibrate[i]);                sb.append(',');            }            if (N != -1) {                sb.append(this.vibrate[N]);            }            sb.append("]");        } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {            sb.append("default");        } else {            sb.append("null");        }        sb.append(",sound=");        if (this.sound != null) {            sb.append(this.sound.toString());        } else if ((this.defaults & DEFAULT_SOUND) != 0) {            sb.append("default");        } else {            sb.append("null");        }        sb.append(",defaults=0x");        sb.append(Integer.toHexString(this.defaults));        sb.append(",flags=0x");        sb.append(Integer.toHexString(this.flags));        if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {            sb.append("!!!1!one!");        }        sb.append(")");        return sb.toString();    }

toString()方法。

建造者(Builder)

首先,Builder类是一个静态内部类:
public static class Builder {

里面使用到的全局变量:
private Context mContext;        private long mWhen;        private int mSmallIcon;        private int mSmallIconLevel;        private int mNumber;        private CharSequence mContentTitle;        private CharSequence mContentText;        private CharSequence mContentInfo;        private PendingIntent mContentIntent;        private RemoteViews mContentView;        private PendingIntent mDeleteIntent;        private PendingIntent mFullScreenIntent;        private CharSequence mTickerText;        private RemoteViews mTickerView;        private Bitmap mLargeIcon;        private Uri mSound;        private int mAudioStreamType;        private long[] mVibrate;        private int mLedArgb;        private int mLedOnMs;        private int mLedOffMs;        private int mDefaults;        private int mFlags;        private int mProgressMax;        private int mProgress;        private boolean mProgressIndeterminate;

参考上面Notification的全局变量。 构造函数:
/**         * Constructor.         *         * Automatically sets the when field to {@link System#currentTimeMillis()         * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.         *         * @param context A {@link Context} that will be used to construct the         *      RemoteViews. The Context will not be held past the lifetime of this         *      Builder object.         */        public Builder(Context context) {            mContext = context;            // Set defaults to match the defaults of a Notification            mWhen = System.currentTimeMillis();            mAudioStreamType = STREAM_DEFAULT;        }

需要传入一个Context,然后获取下当前时间,设置下视频流类型。 设置当前事件时间:系统会根据这个时间在状态栏上为Notification排序。
        /**         * Set the time that the event occurred.  Notifications in the panel are         * sorted by this time.         */        public Builder setWhen(long when) {            mWhen = when;            return this;        }

设置图标:
   /**    * Set the small icon to use in the notification layouts. Different classes of devices    * may return different sizes. See the UX guidelines for more information on how to    * design these icons.    *    * @param icon A resource ID in the application's package of the drawble to use.    */    public Builder setSmallIcon(int icon) {      mSmallIcon = icon;      return this;    }    /**    * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional    * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable    * LevelListDrawable}.    *    * @param icon A resource ID in the application's package of the drawble to use.    * @param level The level to use for the icon.    *    * @see android.graphics.drawable.LevelListDrawable    */    public Builder setSmallIcon(int icon, int level) {      mSmallIcon = icon;      mSmallIconLevel = level;      return this;    }

设置Notification布局的小图标,不同的硬件设备会显示不同的尺寸。可以查看UX文档获取更多如何设计图标的信息。 设置内容标题:
 /**         * Set the title (first row) of the notification, in a standard notification.         */        public Builder setContentTitle(CharSequence title) {            mContentTitle = title;            return this;        }

设置Notification的第一行标题。
设置内容:
/**         * Set the text (second row) of the notification, in a standard notification.         */        public Builder setContentText(CharSequence text) {            mContentText = text;            return this;        }

设置Notification的第二行内容。
设置Notification右侧数字:
/**         * Set the large number at the right-hand side of the notification.  This is         * equivalent to setContentInfo, although it might show the number in a different         * font size for readability.         */        public Builder setNumber(int number) {            mNumber = number;            return this;        }

设置在状态栏右侧显示的数字,等同于setContentInfo,也可以显示数字。 设置Notification右侧显示的文本:
/**         * Set the large text at the right-hand side of the notification.         */        public Builder setContentInfo(CharSequence info) {            mContentInfo = info;            return this;        }

设置进度:
/**         * Set the progress this notification represents, which may be         * represented as a {@link ProgressBar}.         */        public Builder setProgress(int max, int progress, boolean indeterminate) {            mProgressMax = max;            mProgress = progress;            mProgressIndeterminate = indeterminate;            return this;        }

Notification就相当于一个ProgrssBar。
设置内容视图:
**         * Supply a custom RemoteViews to use instead of the standard one.         */        public Builder setContent(RemoteViews views) {            mContentView = views;            return this;        }

使用自定义视图替代标准视图。
设置PendingIntent:
/**         * Supply a {@link PendingIntent} to send when the notification is clicked.         * If you do not supply an intent, you can now add PendingIntents to individual         * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.  Be sure to         * read {@link Notification#contentIntent Notification.contentIntent} for         * how to correctly use this.         */        public Builder setContentIntent(PendingIntent intent) {            mContentIntent = intent;            return this;        }
当Notification被点击时提供一个PendingIntent,如果没有提供这个intent,可以在点击时调用RemoteViews.setOnclickPendingIntent(int,PendingIntent)去设置一个PendingIntent.
设置DeleteIntent:
/**         * Supply a {@link PendingIntent} to send when the notification is cleared by the user         * directly from the notification panel.  For example, this intent is sent when the user         * clicks the "Clear all" button, or the individual "X" buttons on notifications.  This         * intent is not sent when the application calls {@link NotificationManager#cancel         * NotificationManager.cancel(int)}.         */        public Builder setDeleteIntent(PendingIntent intent) {            mDeleteIntent = intent;            return this;        }

设置一个当用户清除状态栏中的Notification是触发的PendingIntent。
设置FullScreenIntent:
 /**         * An intent to launch instead of posting the notification to the status bar.         * Only for use with extremely high-priority notifications demanding the user's         * <strong>immediate</strong> attention, such as an incoming phone call or         * alarm clock that the user has explicitly set to a particular time.         * If this facility is used for something else, please give the user an option         * to turn it off and use a normal notification, as this can be extremely         * disruptive.         *         * @param intent The pending intent to launch.         * @param highPriority Passing true will cause this notification to be sent         *          even if other notifications are suppressed.         */        public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {            mFullScreenIntent = intent;            setFlag(FLAG_HIGH_PRIORITY, highPriority);            return this;        }

一个全屏状态下替代状态栏上的Notification的intent,仅适用于使用非常高的优先级通知,会引起用户的即时关注,如用户已显式设置为一个特定的时间,一个来电或闹钟。
设置TickerText:
/**    * Set the text that is displayed in the status bar when the notification first    * arrives.    */    public Builder setTicker(CharSequence tickerText) {      mTickerText = tickerText;      return this;    }    /**    * Set the text that is displayed in the status bar when the notification first    * arrives, and also a RemoteViews object that may be displayed instead on some    * devices.    */    public Builder setTicker(CharSequence tickerText, RemoteViews views) {      mTickerText = tickerText;      mTickerView = views;      return this;    }
设置 Notification第一次到达时在status Bar 上面显示的文本,第二个方法里面还可以设置一个自定义视图。

设置大图标:
/**         * Set the large icon that is shown in the ticker and notification.         */        public Builder setLargeIcon(Bitmap icon) {            mLargeIcon = icon;            return this;        }


设置声音:
/**    * Set the sound to play. It will play on the default stream.    */    public Builder setSound(Uri sound) {      mSound = sound;      mAudioStreamType = STREAM_DEFAULT;      return this;    }    /**    * Set the sound to play. It will play on the stream you supply.    *    * @see #STREAM_DEFAULT    * @see AudioManager for the <code>STREAM_</code> constants.    */    public Builder setSound(Uri sound, int streamType) {      mSound = sound;      mAudioStreamType = streamType;      return this;    }


设置震动:
/**         * Set the vibration pattern to use.         *         * @see android.os.Vibrator for a discussion of the <code>pattern</code>         * parameter.         */        public Builder setVibrate(long[] pattern) {            mVibrate = pattern;            return this;        }

设置LED灯光:
/**         * Set the argb value that you would like the LED on the device to blnk, as well as the         * rate.  The rate is specified in terms of the number of milliseconds to be on         * and then the number of milliseconds to be off.         */        public Builder setLights(int argb, int onMs, int offMs) {            mLedArgb = argb;            mLedOnMs = onMs;            mLedOffMs = offMs;            return this;        }

设置Ongoing:
 /**         * Set whether this is an ongoing notification.         *         * <p>Ongoing notifications differ from regular notifications in the following ways:         * <ul>         *   <li>Ongoing notifications are sorted above the regular notifications in the         *   notification panel.</li>         *   <li>Ongoing notifications do not have an 'X' close button, and are not affected         *   by the "Clear all" button.         * </ul>         */        public Builder setOngoing(boolean ongoing) {            setFlag(FLAG_ONGOING_EVENT, ongoing);            return this;        }

设置Notification是否是正在进行。 设置是否只提示一次:
/**         * Set this flag if you would only like the sound, vibrate         * and ticker to be played if the notification is not already showing.         */        public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {            setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);            return this;        }

设置是否自动取消:
/**         * Setting this flag will make it so the notification is automatically         * canceled when the user clicks it in the panel.  The PendingIntent         * set with {@link #setDeleteIntent} will be broadcast when the notification         * is canceled.         */        public Builder setAutoCancel(boolean autoCancel) {            setFlag(FLAG_AUTO_CANCEL, autoCancel);            return this;        }

里面都用的私有setFlag方法:
 private void setFlag(int mask, boolean value) {            if (value) {                mFlags |= mask;            } else {                mFlags &= ~mask;            }        }

使用默认设置:
/**         * Set the default notification options that will be used.         * <p>         * The value should be one or more of the following fields combined with         * bitwise-or:         * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.         * <p>         * For all default values, use {@link #DEFAULT_ALL}.         */        public Builder setDefaults(int defaults) {            mDefaults = defaults;            return this;        }

通过ID获取notification视图:
 private RemoteViews makeRemoteViews(int resId) {            RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);            boolean hasLine3 = false;            if (mSmallIcon != 0) {                contentView.setImageViewResource(R.id.icon, mSmallIcon);                contentView.setViewVisibility(R.id.icon, View.VISIBLE);            } else {                contentView.setViewVisibility(R.id.icon, View.GONE);            }            if (mContentTitle != null) {                contentView.setTextViewText(R.id.title, mContentTitle);            }            if (mContentText != null) {                contentView.setTextViewText(R.id.text, mContentText);                hasLine3 = true;            }            if (mContentInfo != null) {                contentView.setTextViewText(R.id.info, mContentInfo);                contentView.setViewVisibility(R.id.info, View.VISIBLE);                hasLine3 = true;            } else if (mNumber > 0) {                final int tooBig = mContext.getResources().getInteger(                        R.integer.status_bar_notification_info_maxnum);                if (mNumber > tooBig) {                    contentView.setTextViewText(R.id.info, mContext.getResources().getString(                                R.string.status_bar_notification_info_overflow));                } else {                    NumberFormat f = NumberFormat.getIntegerInstance();                    contentView.setTextViewText(R.id.info, f.format(mNumber));                }                contentView.setViewVisibility(R.id.info, View.VISIBLE);                hasLine3 = true;            } else {                contentView.setViewVisibility(R.id.info, View.GONE);            }            if (mProgressMax != 0 || mProgressIndeterminate) {                contentView.setProgressBar(                        R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);                contentView.setViewVisibility(R.id.progress, View.VISIBLE);            } else {                contentView.setViewVisibility(R.id.progress, View.GONE);            }            if (mWhen != 0) {                contentView.setLong(R.id.time, "setTime", mWhen);            }            contentView.setViewVisibility(R.id.line3, hasLine3 ? View.VISIBLE : View.GONE);            return contentView;        }

获取默认视图:
private RemoteViews makeContentView() {            if (mContentView != null) {                return mContentView;            } else {                    return makeRemoteViews(mLargeIcon == null                            ? R.layout.status_bar_latest_event_content                        : R.layout.status_bar_latest_event_content_large_icon);            }        }

获取TickerView:
 private RemoteViews makeTickerView() {            if (mTickerView != null) {                return mTickerView;            } else {                if (mContentView == null) {                    return makeRemoteViews(mLargeIcon == null                            ? R.layout.status_bar_latest_event_ticker                            : R.layout.status_bar_latest_event_ticker_large_icon);                } else {                    return null;                }            }        }

注意上面三个方法均是私有方法,在外部不能访问,在下面的方法中调用到了这些方法


通过Builder最后获取一个Notification:
 /**         * Combine all of the options that have been set and return a new {@link Notification}         * object.         */        public Notification getNotification() {            Notification n = new Notification();            n.when = mWhen;            n.icon = mSmallIcon;            n.iconLevel = mSmallIconLevel;            n.number = mNumber;            n.contentView = makeContentView();            n.contentIntent = mContentIntent;            n.deleteIntent = mDeleteIntent;            n.fullScreenIntent = mFullScreenIntent;            n.tickerText = mTickerText;            n.tickerView = makeTickerView();            n.largeIcon = mLargeIcon;            n.sound = mSound;            n.audioStreamType = mAudioStreamType;            n.vibrate = mVibrate;            n.ledARGB = mLedArgb;            n.ledOnMS = mLedOnMs;            n.ledOffMS = mLedOffMs;            n.defaults = mDefaults;            n.flags = mFlags;            if (mLedOnMs != 0 && mLedOffMs != 0) {                n.flags |= FLAG_SHOW_LIGHTS;            }            if ((mDefaults & DEFAULT_LIGHTS) != 0) {                n.flags |= FLAG_SHOW_LIGHTS;            }            return n;        }

Builder的最后,提供一个完整的产品出来。

PS: 写到这,正文部分大体完成,现在时间也已经是晚上11点钟,1000多行的代码,推迟了3天才把文章写完,进度确实有点慢,最近在读凯利麦格尼格尔女士的《自控力》这本书,看到“道德许可效应”,解决了自己关于很多事情的疑问。还没有读完,感觉是一本不错的书籍,推荐一下。 另外,周五有次重要的谈话,祝自己顺利。

更多相关文章

  1. android 布局
  2. TabHost 相关解决
  3. EditText的属性!
  4. View类的XML属性、相关方法及说明
  5. Android(安卓)activity属性设置大全
  6. 清单文件,测试,打电话和发短信应用
  7. Android获取当前时间
  8. Android,TextView的所有属性和方法
  9. Android监听软键盘的方式

随机推荐

  1. 一个现代化的JSON库Moshi针对Android和Ja
  2. Android Selector
  3. Android事件分发机制完全解析,带你从源码
  4. Android NDK初识
  5. android中自己画一个按钮,和自己设置一个
  6. Android:可复制的TextView、EditText
  7. Android: 显示系统模块加载以及调用流程
  8. Android推送通知指南
  9. Android:AsyncTask使用
  10. [置顶] 《Android 之美 从0到1 -- 高手之