Notification.java revision d24b8183b93e781080b2c16c487e60d51c12da31
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import java.util.Date;
20
21import android.app.PendingIntent;
22import android.content.Context;
23import android.content.Intent;
24import android.media.AudioManager;
25import android.net.Uri;
26import android.os.Parcel;
27import android.os.Parcelable;
28import android.text.TextUtils;
29import android.text.format.DateFormat;
30import android.text.format.DateUtils;
31import android.widget.RemoteViews;
32
33/**
34 * A class that represents how a persistent notification is to be presented to
35 * the user using the {@link android.app.NotificationManager}.
36 *
37 */
38public class Notification implements Parcelable
39{
40    /**
41     * Use all default values (where applicable).
42     */
43    public static final int DEFAULT_ALL = ~0;
44
45    /**
46     * Use the default notification sound. This will ignore any given
47     * {@link #sound}.
48     *
49     * @see #defaults
50     */
51    public static final int DEFAULT_SOUND = 1;
52
53    /**
54     * Use the default notification vibrate. This will ignore any given
55     * {@link #vibrate}.
56     *
57     * @see #defaults
58     */
59    public static final int DEFAULT_VIBRATE = 2;
60
61    /**
62     * Use the default notification lights. This will ignore the
63     * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
64     * {@link #ledOnMS}.
65     *
66     * @see #defaults
67     */
68    public static final int DEFAULT_LIGHTS = 4;
69
70    /**
71     * The timestamp for the notification.  The icons and expanded views
72     * are sorted by this key.
73     */
74    public long when;
75
76    /**
77     * The resource id of a drawable to use as the icon in the status bar.
78     */
79    public int icon;
80
81    /**
82     * The number of events that this notification represents.  For example, if this is the
83     * new mail notification, this would be the number of unread messages.  This number is
84     * be superimposed over the icon in the status bar.  If the number is 0 or negative, it
85     * is not shown in the status bar.
86     */
87    public int number;
88
89    /**
90     * The intent to execute when the expanded status entry is clicked.  If
91     * this is an activity, it must include the
92     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
93     * that you take care of task management as described in the <em>Activities and Tasks</em>
94     * section of the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application
95     * Fundamentals</a> document.
96     */
97    public PendingIntent contentIntent;
98
99    /**
100     * The intent to execute when the status entry is deleted by the user
101     * with the "Clear All Notifications" button. This probably shouldn't
102     * be launching an activity since several of those will be sent at the
103     * same time.
104     */
105    public PendingIntent deleteIntent;
106
107    /**
108     * Text to scroll across the screen when this item is added to
109     * the status bar.
110     */
111    public CharSequence tickerText;
112
113    /**
114     * The view that shows when this notification is shown in the expanded status bar.
115     */
116    public RemoteViews contentView;
117
118    /**
119     * If the icon in the status bar is to have more than one level, you can set this.  Otherwise,
120     * leave it at its default value of 0.
121     *
122     * @see android.widget.ImageView#setImageLevel
123     * @see android.graphics.drawable#setLevel
124     */
125    public int iconLevel;
126
127    /**
128     * The sound to play.
129     *
130     * <p>
131     * To play the default notification sound, see {@link #defaults}.
132     * </p>
133     */
134    public Uri sound;
135
136    /**
137     * Use this constant as the value for audioStreamType to request that
138     * the default stream type for notifications be used.  Currently the
139     * default stream type is STREAM_RING.
140     */
141    public static final int STREAM_DEFAULT = -1;
142
143    /**
144     * The audio stream type to use when playing the sound.
145     * Should be one of the STREAM_ constants from
146     * {@link android.media.AudioManager}.
147     */
148    public int audioStreamType = STREAM_DEFAULT;
149
150
151    /**
152     * The pattern with which to vibrate. This pattern will repeat if {@link
153     * #FLAG_INSISTENT} bit is set in the {@link #flags} field.
154     *
155     * <p>
156     * To vibrate the default pattern, see {@link #defaults}.
157     * </p>
158     *
159     * @see android.os.Vibrator#vibrate(long[],int)
160     */
161    public long[] vibrate;
162
163    /**
164     * The color of the led.  The hardware will do its best approximation.
165     *
166     * @see #FLAG_SHOW_LIGHTS
167     * @see #flags
168     */
169    public int ledARGB;
170
171    /**
172     * The number of milliseconds for the LED to be on while it's flashing.
173     * The hardware will do its best approximation.
174     *
175     * @see #FLAG_SHOW_LIGHTS
176     * @see #flags
177     */
178    public int ledOnMS;
179
180    /**
181     * The number of milliseconds for the LED to be off while it's flashing.
182     * The hardware will do its best approximation.
183     *
184     * @see #FLAG_SHOW_LIGHTS
185     * @see #flags
186     */
187    public int ledOffMS;
188
189    /**
190     * Specifies which values should be taken from the defaults.
191     * <p>
192     * To set, OR the desired from {@link #DEFAULT_SOUND},
193     * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
194     * values, use {@link #DEFAULT_ALL}.
195     * </p>
196     */
197    public int defaults;
198
199
200    /**
201     * Bit to be bitwise-ored into the {@link #flags} field that should be
202     * set if you want the LED on for this notification.
203     * <ul>
204     * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
205     *      or 0 for both ledOnMS and ledOffMS.</li>
206     * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
207     * <li>To flash the LED, pass the number of milliseconds that it should
208     *      be on and off to ledOnMS and ledOffMS.</li>
209     * </ul>
210     * <p>
211     * Since hardware varies, you are not guaranteed that any of the values
212     * you pass are honored exactly.  Use the system defaults (TODO) if possible
213     * because they will be set to values that work on any given hardware.
214     * <p>
215     * The alpha channel must be set for forward compatibility.
216     *
217     */
218    public static final int FLAG_SHOW_LIGHTS        = 0x00000001;
219
220    /**
221     * Bit to be bitwise-ored into the {@link #flags} field that should be
222     * set if this notification is in reference to something that is ongoing,
223     * like a phone call.  It should not be set if this notification is in
224     * reference to something that happened at a particular point in time,
225     * like a missed phone call.
226     */
227    public static final int FLAG_ONGOING_EVENT      = 0x00000002;
228
229    /**
230     * Bit to be bitwise-ored into the {@link #flags} field that if set,
231     * the audio and vibration will be repeated until the notification is
232     * cancelled.
233     *
234     * <p>
235     * NOTE: This notion will change when we have decided exactly
236     * what the UI will be.
237     * </p>
238     */
239    public static final int FLAG_INSISTENT          = 0x00000004;
240
241    /**
242     * Bit to be bitwise-ored into the {@link #flags} field that should be
243     * set if you want the sound and/or vibration play each time the
244     * notification is sent, even if it has not been canceled before that.
245     */
246    public static final int FLAG_ONLY_ALERT_ONCE    = 0x00000008;
247
248    /**
249     * Bit to be bitwise-ored into the {@link #flags} field that should be
250     * set if the notification should be canceled when it is clicked by the
251     * user.
252     */
253    public static final int FLAG_AUTO_CANCEL        = 0x00000010;
254
255    /**
256     * Bit to be bitwise-ored into the {@link #flags} field that should be
257     * set if the notification should not be canceled when the user clicks
258     * the Clear all button.
259     */
260    public static final int FLAG_NO_CLEAR           = 0x00000020;
261
262    public int flags;
263
264    /**
265     * Constructs a Notification object with everything set to 0.
266     */
267    public Notification()
268    {
269        this.when = System.currentTimeMillis();
270    }
271
272    /**
273     * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
274     * @hide
275     */
276    public Notification(Context context, int icon, CharSequence tickerText, long when,
277            CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
278    {
279        this.when = when;
280        this.icon = icon;
281        this.tickerText = tickerText;
282        setLatestEventInfo(context, contentTitle, contentText,
283                PendingIntent.getActivity(context, 0, contentIntent, 0));
284    }
285
286    /**
287     * Constructs a Notification object with the information needed to
288     * have a status bar icon without the standard expanded view.
289     *
290     * @param icon          The resource id of the icon to put in the status bar.
291     * @param tickerText    The text that flows by in the status bar when the notification first
292     *                      activates.
293     * @param when          The time to show in the time field.  In the System.currentTimeMillis
294     *                      timebase.
295     */
296    public Notification(int icon, CharSequence tickerText, long when)
297    {
298        this.icon = icon;
299        this.tickerText = tickerText;
300        this.when = when;
301    }
302
303    /**
304     * Unflatten the notification from a parcel.
305     */
306    public Notification(Parcel parcel)
307    {
308        int version = parcel.readInt();
309
310        when = parcel.readLong();
311        icon = parcel.readInt();
312        number = parcel.readInt();
313        if (parcel.readInt() != 0) {
314            contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
315        }
316        if (parcel.readInt() != 0) {
317            deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
318        }
319        if (parcel.readInt() != 0) {
320            tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
321        }
322        if (parcel.readInt() != 0) {
323            contentView = RemoteViews.CREATOR.createFromParcel(parcel);
324        }
325        defaults = parcel.readInt();
326        flags = parcel.readInt();
327        if (parcel.readInt() != 0) {
328            sound = Uri.CREATOR.createFromParcel(parcel);
329        }
330
331        audioStreamType = parcel.readInt();
332        vibrate = parcel.createLongArray();
333        ledARGB = parcel.readInt();
334        ledOnMS = parcel.readInt();
335        ledOffMS = parcel.readInt();
336        iconLevel = parcel.readInt();
337    }
338
339    public int describeContents() {
340        return 0;
341    }
342
343    /**
344     * Flatten this notification from a parcel.
345     */
346    public void writeToParcel(Parcel parcel, int flags)
347    {
348        parcel.writeInt(1);
349
350        parcel.writeLong(when);
351        parcel.writeInt(icon);
352        parcel.writeInt(number);
353        if (contentIntent != null) {
354            parcel.writeInt(1);
355            contentIntent.writeToParcel(parcel, 0);
356        } else {
357            parcel.writeInt(0);
358        }
359        if (deleteIntent != null) {
360            parcel.writeInt(1);
361            deleteIntent.writeToParcel(parcel, 0);
362        } else {
363            parcel.writeInt(0);
364        }
365        if (tickerText != null) {
366            parcel.writeInt(1);
367            TextUtils.writeToParcel(tickerText, parcel, flags);
368        } else {
369            parcel.writeInt(0);
370        }
371        if (contentView != null) {
372            parcel.writeInt(1);
373            contentView.writeToParcel(parcel, 0);
374        } else {
375            parcel.writeInt(0);
376        }
377
378        parcel.writeInt(defaults);
379        parcel.writeInt(this.flags);
380
381        if (sound != null) {
382            parcel.writeInt(1);
383            sound.writeToParcel(parcel, 0);
384        } else {
385            parcel.writeInt(0);
386        }
387        parcel.writeInt(audioStreamType);
388        parcel.writeLongArray(vibrate);
389        parcel.writeInt(ledARGB);
390        parcel.writeInt(ledOnMS);
391        parcel.writeInt(ledOffMS);
392        parcel.writeInt(iconLevel);
393    }
394
395    /**
396     * Parcelable.Creator that instantiates Notification objects
397     */
398    public static final Parcelable.Creator<Notification> CREATOR
399            = new Parcelable.Creator<Notification>()
400    {
401        public Notification createFromParcel(Parcel parcel)
402        {
403            return new Notification(parcel);
404        }
405
406        public Notification[] newArray(int size)
407        {
408            return new Notification[size];
409        }
410    };
411
412    /**
413     * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
414     * layout.
415     *
416     * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
417     * in the view.</p>
418     * @param context       The context for your application / activity.
419     * @param contentTitle The title that goes in the expanded entry.
420     * @param contentText  The text that goes in the expanded entry.
421     * @param contentIntent The intent to launch when the user clicks the expanded notification.
422     * If this is an activity, it must include the
423     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
424     * that you take care of task management as described in
425     * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
426     */
427    public void setLatestEventInfo(Context context,
428            CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
429        RemoteViews contentView = new RemoteViews(context.getPackageName(),
430                com.android.internal.R.layout.status_bar_latest_event_content);
431        if (this.icon != 0) {
432            contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
433        }
434        if (contentTitle != null) {
435            contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
436        }
437        if (contentText != null) {
438            contentView.setTextViewText(com.android.internal.R.id.text, contentText);
439        }
440        if (this.when != 0) {
441            Date date = new Date(when);
442            CharSequence str =
443                DateUtils.isToday(when) ? DateFormat.getTimeFormat(context).format(date)
444                    : DateFormat.getDateFormat(context).format(date);
445            contentView.setTextViewText(com.android.internal.R.id.time, str);
446        }
447
448        this.contentView = contentView;
449        this.contentIntent = contentIntent;
450    }
451
452    @Override
453    public String toString() {
454        StringBuilder sb = new StringBuilder();
455        sb.append("Notification(vibrate=");
456        if (this.vibrate != null) {
457            int N = this.vibrate.length-1;
458            sb.append("[");
459            for (int i=0; i<N; i++) {
460                sb.append(this.vibrate[i]);
461                sb.append(',');
462            }
463            sb.append(this.vibrate[N]);
464            sb.append("]");
465        } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
466            sb.append("default");
467        } else {
468            sb.append("null");
469        }
470        sb.append(",sound=");
471        if (this.sound != null) {
472            sb.append(this.sound.toString());
473        } else if ((this.defaults & DEFAULT_SOUND) != 0) {
474            sb.append("default");
475        } else {
476            sb.append("null");
477        }
478        sb.append(",defaults=0x");
479        sb.append(Integer.toHexString(this.defaults));
480        sb.append(")");
481        return sb.toString();
482    }
483}
484