blob: 83a202409df05b9898d14c5b58a83714c6171065 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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 *
Scott Mainb8b36452009-04-26 15:50:49 -070037 * <p>For a guide to creating notifications, see the
38 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
39 * Bar Notifications</a> document in the Dev Guide.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 */
41public class Notification implements Parcelable
42{
43 /**
44 * Use all default values (where applicable).
45 */
46 public static final int DEFAULT_ALL = ~0;
47
48 /**
49 * Use the default notification sound. This will ignore any given
50 * {@link #sound}.
51 *
52 * @see #defaults
53 */
54 public static final int DEFAULT_SOUND = 1;
55
56 /**
57 * Use the default notification vibrate. This will ignore any given
Scott Mainb8b36452009-04-26 15:50:49 -070058 * {@link #vibrate}. Using phone vibration requires the
59 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 *
61 * @see #defaults
62 */
63 public static final int DEFAULT_VIBRATE = 2;
64
65 /**
66 * Use the default notification lights. This will ignore the
67 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
68 * {@link #ledOnMS}.
69 *
70 * @see #defaults
71 */
72 public static final int DEFAULT_LIGHTS = 4;
73
74 /**
75 * The timestamp for the notification. The icons and expanded views
76 * are sorted by this key.
77 */
78 public long when;
79
80 /**
81 * The resource id of a drawable to use as the icon in the status bar.
82 */
83 public int icon;
84
85 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -040086 * The number of events that this notification represents. For example, in a new mail
87 * notification, this could be the number of unread messages. This number is superimposed over
88 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
89 * bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 */
91 public int number;
92
93 /**
94 * The intent to execute when the expanded status entry is clicked. If
95 * this is an activity, it must include the
96 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
97 * that you take care of task management as described in the <em>Activities and Tasks</em>
98 * section of the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application
99 * Fundamentals</a> document.
100 */
101 public PendingIntent contentIntent;
102
103 /**
104 * The intent to execute when the status entry is deleted by the user
105 * with the "Clear All Notifications" button. This probably shouldn't
106 * be launching an activity since several of those will be sent at the
107 * same time.
108 */
109 public PendingIntent deleteIntent;
110
111 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400112 * An intent to launch instead of posting the notification to the status bar. Only for use with
113 * extremely high-priority notifications demanding the user's attention, such as an incoming
114 * call (handled in the core Android Phone app with a full-screen Activity).
115 * Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification will reach the user
116 * even when other notifications are suppressed.
117 */
118 public PendingIntent fullScreenIntent;
119
120 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 * Text to scroll across the screen when this item is added to
122 * the status bar.
123 */
124 public CharSequence tickerText;
125
126 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400127 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 */
129 public RemoteViews contentView;
130
131 /**
132 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
133 * leave it at its default value of 0.
134 *
135 * @see android.widget.ImageView#setImageLevel
136 * @see android.graphics.drawable#setLevel
137 */
138 public int iconLevel;
139
140 /**
141 * The sound to play.
142 *
143 * <p>
144 * To play the default notification sound, see {@link #defaults}.
145 * </p>
146 */
147 public Uri sound;
148
149 /**
150 * Use this constant as the value for audioStreamType to request that
151 * the default stream type for notifications be used. Currently the
152 * default stream type is STREAM_RING.
153 */
154 public static final int STREAM_DEFAULT = -1;
155
156 /**
157 * The audio stream type to use when playing the sound.
158 * Should be one of the STREAM_ constants from
159 * {@link android.media.AudioManager}.
160 */
161 public int audioStreamType = STREAM_DEFAULT;
162
163
164 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700165 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 *
167 * <p>
168 * To vibrate the default pattern, see {@link #defaults}.
169 * </p>
170 *
171 * @see android.os.Vibrator#vibrate(long[],int)
172 */
173 public long[] vibrate;
174
175 /**
176 * The color of the led. The hardware will do its best approximation.
177 *
178 * @see #FLAG_SHOW_LIGHTS
179 * @see #flags
180 */
181 public int ledARGB;
182
183 /**
184 * The number of milliseconds for the LED to be on while it's flashing.
185 * The hardware will do its best approximation.
186 *
187 * @see #FLAG_SHOW_LIGHTS
188 * @see #flags
189 */
190 public int ledOnMS;
191
192 /**
193 * The number of milliseconds for the LED to be off while it's flashing.
194 * The hardware will do its best approximation.
195 *
196 * @see #FLAG_SHOW_LIGHTS
197 * @see #flags
198 */
199 public int ledOffMS;
200
201 /**
202 * Specifies which values should be taken from the defaults.
203 * <p>
204 * To set, OR the desired from {@link #DEFAULT_SOUND},
205 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
206 * values, use {@link #DEFAULT_ALL}.
207 * </p>
208 */
209 public int defaults;
210
211
212 /**
213 * Bit to be bitwise-ored into the {@link #flags} field that should be
214 * set if you want the LED on for this notification.
215 * <ul>
216 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
217 * or 0 for both ledOnMS and ledOffMS.</li>
218 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
219 * <li>To flash the LED, pass the number of milliseconds that it should
220 * be on and off to ledOnMS and ledOffMS.</li>
221 * </ul>
222 * <p>
223 * Since hardware varies, you are not guaranteed that any of the values
224 * you pass are honored exactly. Use the system defaults (TODO) if possible
225 * because they will be set to values that work on any given hardware.
226 * <p>
227 * The alpha channel must be set for forward compatibility.
228 *
229 */
230 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
231
232 /**
233 * Bit to be bitwise-ored into the {@link #flags} field that should be
234 * set if this notification is in reference to something that is ongoing,
235 * like a phone call. It should not be set if this notification is in
236 * reference to something that happened at a particular point in time,
237 * like a missed phone call.
238 */
239 public static final int FLAG_ONGOING_EVENT = 0x00000002;
240
241 /**
242 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700243 * the audio will be repeated until the notification is
244 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 */
246 public static final int FLAG_INSISTENT = 0x00000004;
247
248 /**
249 * Bit to be bitwise-ored into the {@link #flags} field that should be
250 * set if you want the sound and/or vibration play each time the
251 * notification is sent, even if it has not been canceled before that.
252 */
253 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
254
255 /**
256 * Bit to be bitwise-ored into the {@link #flags} field that should be
257 * set if the notification should be canceled when it is clicked by the
258 * user.
259 */
260 public static final int FLAG_AUTO_CANCEL = 0x00000010;
261
262 /**
263 * Bit to be bitwise-ored into the {@link #flags} field that should be
264 * set if the notification should not be canceled when the user clicks
265 * the Clear all button.
266 */
267 public static final int FLAG_NO_CLEAR = 0x00000020;
268
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700269 /**
270 * Bit to be bitwise-ored into the {@link #flags} field that should be
271 * set if this notification represents a currently running service. This
272 * will normally be set for you by {@link Service#startForeground}.
273 */
274 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
275
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400276 /**
277 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
278 * represents a high-priority event that may be shown to the user even if notifications are
279 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
280 * in conjunction with {@link #fullScreenIntent}.
281 */
282 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 public int flags;
285
286 /**
287 * Constructs a Notification object with everything set to 0.
288 */
289 public Notification()
290 {
291 this.when = System.currentTimeMillis();
292 }
293
294 /**
295 * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
296 * @hide
297 */
298 public Notification(Context context, int icon, CharSequence tickerText, long when,
299 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
300 {
301 this.when = when;
302 this.icon = icon;
303 this.tickerText = tickerText;
304 setLatestEventInfo(context, contentTitle, contentText,
305 PendingIntent.getActivity(context, 0, contentIntent, 0));
306 }
307
308 /**
309 * Constructs a Notification object with the information needed to
310 * have a status bar icon without the standard expanded view.
311 *
312 * @param icon The resource id of the icon to put in the status bar.
313 * @param tickerText The text that flows by in the status bar when the notification first
314 * activates.
315 * @param when The time to show in the time field. In the System.currentTimeMillis
316 * timebase.
317 */
318 public Notification(int icon, CharSequence tickerText, long when)
319 {
320 this.icon = icon;
321 this.tickerText = tickerText;
322 this.when = when;
323 }
324
325 /**
326 * Unflatten the notification from a parcel.
327 */
328 public Notification(Parcel parcel)
329 {
330 int version = parcel.readInt();
331
332 when = parcel.readLong();
333 icon = parcel.readInt();
334 number = parcel.readInt();
335 if (parcel.readInt() != 0) {
336 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
337 }
338 if (parcel.readInt() != 0) {
339 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
340 }
341 if (parcel.readInt() != 0) {
342 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
343 }
344 if (parcel.readInt() != 0) {
345 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
346 }
347 defaults = parcel.readInt();
348 flags = parcel.readInt();
349 if (parcel.readInt() != 0) {
350 sound = Uri.CREATOR.createFromParcel(parcel);
351 }
352
353 audioStreamType = parcel.readInt();
354 vibrate = parcel.createLongArray();
355 ledARGB = parcel.readInt();
356 ledOnMS = parcel.readInt();
357 ledOffMS = parcel.readInt();
358 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400359
360 if (parcel.readInt() != 0) {
361 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 }
364
Joe Onorato18e69df2010-05-17 22:26:12 -0700365 public Notification clone() {
366 Notification that = new Notification();
367
368 that.when = this.when;
369 that.icon = this.icon;
370 that.number = this.number;
371
372 // PendingIntents are global, so there's no reason (or way) to clone them.
373 that.contentIntent = this.contentIntent;
374 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400375 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700376
377 if (this.tickerText != null) {
378 that.tickerText = this.tickerText.toString();
379 }
380 if (this.contentView != null) {
381 that.contentView = this.contentView.clone();
382 }
383 that.iconLevel = that.iconLevel;
384 that.sound = this.sound; // android.net.Uri is immutable
385 that.audioStreamType = this.audioStreamType;
386
387 final long[] vibrate = this.vibrate;
388 if (vibrate != null) {
389 final int N = vibrate.length;
390 final long[] vib = that.vibrate = new long[N];
391 System.arraycopy(vibrate, 0, vib, 0, N);
392 }
393
394 that.ledARGB = this.ledARGB;
395 that.ledOnMS = this.ledOnMS;
396 that.ledOffMS = this.ledOffMS;
397 that.defaults = this.defaults;
398
399 that.flags = this.flags;
400
401 return that;
402 }
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 public int describeContents() {
405 return 0;
406 }
407
408 /**
409 * Flatten this notification from a parcel.
410 */
411 public void writeToParcel(Parcel parcel, int flags)
412 {
413 parcel.writeInt(1);
414
415 parcel.writeLong(when);
416 parcel.writeInt(icon);
417 parcel.writeInt(number);
418 if (contentIntent != null) {
419 parcel.writeInt(1);
420 contentIntent.writeToParcel(parcel, 0);
421 } else {
422 parcel.writeInt(0);
423 }
424 if (deleteIntent != null) {
425 parcel.writeInt(1);
426 deleteIntent.writeToParcel(parcel, 0);
427 } else {
428 parcel.writeInt(0);
429 }
430 if (tickerText != null) {
431 parcel.writeInt(1);
432 TextUtils.writeToParcel(tickerText, parcel, flags);
433 } else {
434 parcel.writeInt(0);
435 }
436 if (contentView != null) {
437 parcel.writeInt(1);
438 contentView.writeToParcel(parcel, 0);
439 } else {
440 parcel.writeInt(0);
441 }
442
443 parcel.writeInt(defaults);
444 parcel.writeInt(this.flags);
445
446 if (sound != null) {
447 parcel.writeInt(1);
448 sound.writeToParcel(parcel, 0);
449 } else {
450 parcel.writeInt(0);
451 }
452 parcel.writeInt(audioStreamType);
453 parcel.writeLongArray(vibrate);
454 parcel.writeInt(ledARGB);
455 parcel.writeInt(ledOnMS);
456 parcel.writeInt(ledOffMS);
457 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400458
459 if (fullScreenIntent != null) {
460 parcel.writeInt(1);
461 fullScreenIntent.writeToParcel(parcel, 0);
462 } else {
463 parcel.writeInt(0);
464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 }
466
467 /**
468 * Parcelable.Creator that instantiates Notification objects
469 */
470 public static final Parcelable.Creator<Notification> CREATOR
471 = new Parcelable.Creator<Notification>()
472 {
473 public Notification createFromParcel(Parcel parcel)
474 {
475 return new Notification(parcel);
476 }
477
478 public Notification[] newArray(int size)
479 {
480 return new Notification[size];
481 }
482 };
483
484 /**
485 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
486 * layout.
487 *
488 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
489 * in the view.</p>
490 * @param context The context for your application / activity.
491 * @param contentTitle The title that goes in the expanded entry.
492 * @param contentText The text that goes in the expanded entry.
493 * @param contentIntent The intent to launch when the user clicks the expanded notification.
494 * If this is an activity, it must include the
495 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
496 * that you take care of task management as described in
497 * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
498 */
499 public void setLatestEventInfo(Context context,
500 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
501 RemoteViews contentView = new RemoteViews(context.getPackageName(),
502 com.android.internal.R.layout.status_bar_latest_event_content);
503 if (this.icon != 0) {
504 contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
505 }
506 if (contentTitle != null) {
507 contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
508 }
509 if (contentText != null) {
510 contentView.setTextViewText(com.android.internal.R.id.text, contentText);
511 }
512 if (this.when != 0) {
Joe Onoratoc83bb732010-01-19 16:32:22 -0800513 contentView.setLong(com.android.internal.R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 }
515
516 this.contentView = contentView;
517 this.contentIntent = contentIntent;
518 }
519
520 @Override
521 public String toString() {
522 StringBuilder sb = new StringBuilder();
523 sb.append("Notification(vibrate=");
524 if (this.vibrate != null) {
525 int N = this.vibrate.length-1;
526 sb.append("[");
527 for (int i=0; i<N; i++) {
528 sb.append(this.vibrate[i]);
529 sb.append(',');
530 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200531 if (N != -1) {
532 sb.append(this.vibrate[N]);
533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 sb.append("]");
535 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
536 sb.append("default");
537 } else {
538 sb.append("null");
539 }
540 sb.append(",sound=");
541 if (this.sound != null) {
542 sb.append(this.sound.toString());
543 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
544 sb.append("default");
545 } else {
546 sb.append("null");
547 }
548 sb.append(",defaults=0x");
549 sb.append(Integer.toHexString(this.defaults));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400550 sb.append(",flags=0x");
551 sb.append(Integer.toHexString(this.flags));
552 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
553 sb.append("!!!1!one!");
554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 sb.append(")");
556 return sb.toString();
557 }
558}