blob: 9490b96b4f8d116d2d879c16dfb00d9cbd131e9f [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
Andy Stadler110988c2010-12-03 14:29:16 -080019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
22import android.content.Intent;
Joe Onoratoef1e7762010-09-17 18:38:38 -040023import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.net.Uri;
25import android.os.Parcel;
26import android.os.Parcelable;
27import android.text.TextUtils;
Joe Onorato8595a3d2010-11-19 18:12:07 -080028import android.view.View;
Jeff Sharkey1c400132011-08-05 14:50:13 -070029import android.widget.ProgressBar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.widget.RemoteViews;
31
Andy Stadler110988c2010-12-03 14:29:16 -080032import java.text.NumberFormat;
Joe Onorato561d3852010-11-20 18:09:34 -080033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034/**
35 * A class that represents how a persistent notification is to be presented to
36 * the user using the {@link android.app.NotificationManager}.
37 *
Joe Onoratocb109a02011-01-18 17:57:41 -080038 * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
39 * easier to construct Notifications.</p>
40 *
Scott Mainb8b36452009-04-26 15:50:49 -070041 * <p>For a guide to creating notifications, see the
42 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
43 * Bar Notifications</a> document in the Dev Guide.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 */
45public class Notification implements Parcelable
46{
47 /**
48 * Use all default values (where applicable).
49 */
50 public static final int DEFAULT_ALL = ~0;
51
52 /**
53 * Use the default notification sound. This will ignore any given
54 * {@link #sound}.
55 *
56 * @see #defaults
57 */
58 public static final int DEFAULT_SOUND = 1;
59
60 /**
61 * Use the default notification vibrate. This will ignore any given
Scott Mainb8b36452009-04-26 15:50:49 -070062 * {@link #vibrate}. Using phone vibration requires the
63 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 *
65 * @see #defaults
66 */
67 public static final int DEFAULT_VIBRATE = 2;
68
69 /**
70 * Use the default notification lights. This will ignore the
71 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
72 * {@link #ledOnMS}.
73 *
74 * @see #defaults
75 */
76 public static final int DEFAULT_LIGHTS = 4;
77
78 /**
79 * The timestamp for the notification. The icons and expanded views
80 * are sorted by this key.
81 */
82 public long when;
83
84 /**
85 * The resource id of a drawable to use as the icon in the status bar.
Daniel Sandlerd952dae2011-02-07 16:33:36 -050086 * This is required; notifications with an invalid icon resource will not be shown.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 */
88 public int icon;
89
90 /**
Joe Onorato46439ce2010-11-19 13:56:21 -080091 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
92 * leave it at its default value of 0.
93 *
94 * @see android.widget.ImageView#setImageLevel
95 * @see android.graphics.drawable#setLevel
96 */
97 public int iconLevel;
98
99 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400100 * The number of events that this notification represents. For example, in a new mail
101 * notification, this could be the number of unread messages. This number is superimposed over
102 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
103 * bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 */
105 public int number;
106
107 /**
108 * The intent to execute when the expanded status entry is clicked. If
109 * this is an activity, it must include the
110 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800111 * that you take care of task management as described in the
112 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
113 * Stack</a> document.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 */
115 public PendingIntent contentIntent;
116
117 /**
118 * The intent to execute when the status entry is deleted by the user
119 * with the "Clear All Notifications" button. This probably shouldn't
120 * be launching an activity since several of those will be sent at the
121 * same time.
122 */
123 public PendingIntent deleteIntent;
124
125 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700126 * An intent to launch instead of posting the notification to the status bar.
Joe Onoratocb109a02011-01-18 17:57:41 -0800127 *
128 * @see Notification.Builder#setFullScreenIntent
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400129 */
130 public PendingIntent fullScreenIntent;
131
132 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 * Text to scroll across the screen when this item is added to
Joe Onoratoef1e7762010-09-17 18:38:38 -0400134 * the status bar on large and smaller devices.
135 *
136 * <p>This field is provided separately from the other ticker fields
137 * both for compatibility and to allow an application to choose different
138 * text for when the text scrolls in and when it is displayed all at once
139 * in conjunction with one or more icons.
140 *
Joe Onorato46439ce2010-11-19 13:56:21 -0800141 * @see #tickerView
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 */
143 public CharSequence tickerText;
144
145 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800146 * The view to show as the ticker in the status bar when the notification
147 * is posted.
Joe Onoratoef1e7762010-09-17 18:38:38 -0400148 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800149 public RemoteViews tickerView;
Joe Onoratoef1e7762010-09-17 18:38:38 -0400150
151 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400152 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 */
154 public RemoteViews contentView;
155
156 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800157 * The bitmap that may escape the bounds of the panel and bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800159 public Bitmap largeIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
161 /**
162 * The sound to play.
163 *
164 * <p>
165 * To play the default notification sound, see {@link #defaults}.
166 * </p>
167 */
168 public Uri sound;
169
170 /**
171 * Use this constant as the value for audioStreamType to request that
172 * the default stream type for notifications be used. Currently the
173 * default stream type is STREAM_RING.
174 */
175 public static final int STREAM_DEFAULT = -1;
176
177 /**
178 * The audio stream type to use when playing the sound.
179 * Should be one of the STREAM_ constants from
180 * {@link android.media.AudioManager}.
181 */
182 public int audioStreamType = STREAM_DEFAULT;
183
184
185 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700186 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 *
188 * <p>
189 * To vibrate the default pattern, see {@link #defaults}.
190 * </p>
191 *
192 * @see android.os.Vibrator#vibrate(long[],int)
193 */
194 public long[] vibrate;
195
196 /**
197 * The color of the led. The hardware will do its best approximation.
198 *
199 * @see #FLAG_SHOW_LIGHTS
200 * @see #flags
201 */
202 public int ledARGB;
203
204 /**
205 * The number of milliseconds for the LED to be on while it's flashing.
206 * The hardware will do its best approximation.
207 *
208 * @see #FLAG_SHOW_LIGHTS
209 * @see #flags
210 */
211 public int ledOnMS;
212
213 /**
214 * The number of milliseconds for the LED to be off while it's flashing.
215 * The hardware will do its best approximation.
216 *
217 * @see #FLAG_SHOW_LIGHTS
218 * @see #flags
219 */
220 public int ledOffMS;
221
222 /**
223 * Specifies which values should be taken from the defaults.
224 * <p>
225 * To set, OR the desired from {@link #DEFAULT_SOUND},
226 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
227 * values, use {@link #DEFAULT_ALL}.
228 * </p>
229 */
230 public int defaults;
231
232
233 /**
234 * Bit to be bitwise-ored into the {@link #flags} field that should be
235 * set if you want the LED on for this notification.
236 * <ul>
237 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
238 * or 0 for both ledOnMS and ledOffMS.</li>
239 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
240 * <li>To flash the LED, pass the number of milliseconds that it should
241 * be on and off to ledOnMS and ledOffMS.</li>
242 * </ul>
243 * <p>
244 * Since hardware varies, you are not guaranteed that any of the values
245 * you pass are honored exactly. Use the system defaults (TODO) if possible
246 * because they will be set to values that work on any given hardware.
247 * <p>
248 * The alpha channel must be set for forward compatibility.
249 *
250 */
251 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
252
253 /**
254 * Bit to be bitwise-ored into the {@link #flags} field that should be
255 * set if this notification is in reference to something that is ongoing,
256 * like a phone call. It should not be set if this notification is in
257 * reference to something that happened at a particular point in time,
258 * like a missed phone call.
259 */
260 public static final int FLAG_ONGOING_EVENT = 0x00000002;
261
262 /**
263 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700264 * the audio will be repeated until the notification is
265 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 */
267 public static final int FLAG_INSISTENT = 0x00000004;
268
269 /**
270 * Bit to be bitwise-ored into the {@link #flags} field that should be
271 * set if you want the sound and/or vibration play each time the
272 * notification is sent, even if it has not been canceled before that.
273 */
274 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
275
276 /**
277 * Bit to be bitwise-ored into the {@link #flags} field that should be
278 * set if the notification should be canceled when it is clicked by the
Joe Onoratocb109a02011-01-18 17:57:41 -0800279 * user. On tablets, the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 */
281 public static final int FLAG_AUTO_CANCEL = 0x00000010;
282
283 /**
284 * Bit to be bitwise-ored into the {@link #flags} field that should be
285 * set if the notification should not be canceled when the user clicks
286 * the Clear all button.
287 */
288 public static final int FLAG_NO_CLEAR = 0x00000020;
289
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700290 /**
291 * Bit to be bitwise-ored into the {@link #flags} field that should be
292 * set if this notification represents a currently running service. This
293 * will normally be set for you by {@link Service#startForeground}.
294 */
295 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
296
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400297 /**
298 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
299 * represents a high-priority event that may be shown to the user even if notifications are
300 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
301 * in conjunction with {@link #fullScreenIntent}.
302 */
303 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 public int flags;
306
307 /**
308 * Constructs a Notification object with everything set to 0.
Joe Onorato46439ce2010-11-19 13:56:21 -0800309 * You might want to consider using {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 */
311 public Notification()
312 {
313 this.when = System.currentTimeMillis();
314 }
315
316 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 * @hide
318 */
319 public Notification(Context context, int icon, CharSequence tickerText, long when,
320 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
321 {
322 this.when = when;
323 this.icon = icon;
324 this.tickerText = tickerText;
325 setLatestEventInfo(context, contentTitle, contentText,
326 PendingIntent.getActivity(context, 0, contentIntent, 0));
327 }
328
329 /**
330 * Constructs a Notification object with the information needed to
331 * have a status bar icon without the standard expanded view.
332 *
333 * @param icon The resource id of the icon to put in the status bar.
334 * @param tickerText The text that flows by in the status bar when the notification first
335 * activates.
336 * @param when The time to show in the time field. In the System.currentTimeMillis
337 * timebase.
Joe Onorato46439ce2010-11-19 13:56:21 -0800338 *
339 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800341 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 public Notification(int icon, CharSequence tickerText, long when)
343 {
344 this.icon = icon;
345 this.tickerText = tickerText;
346 this.when = when;
347 }
348
349 /**
350 * Unflatten the notification from a parcel.
351 */
352 public Notification(Parcel parcel)
353 {
354 int version = parcel.readInt();
355
356 when = parcel.readLong();
357 icon = parcel.readInt();
358 number = parcel.readInt();
359 if (parcel.readInt() != 0) {
360 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
361 }
362 if (parcel.readInt() != 0) {
363 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
364 }
365 if (parcel.readInt() != 0) {
366 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
367 }
368 if (parcel.readInt() != 0) {
Joe Onorato46439ce2010-11-19 13:56:21 -0800369 tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400370 }
371 if (parcel.readInt() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
373 }
Joe Onorato561d3852010-11-20 18:09:34 -0800374 if (parcel.readInt() != 0) {
375 largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 defaults = parcel.readInt();
378 flags = parcel.readInt();
379 if (parcel.readInt() != 0) {
380 sound = Uri.CREATOR.createFromParcel(parcel);
381 }
382
383 audioStreamType = parcel.readInt();
384 vibrate = parcel.createLongArray();
385 ledARGB = parcel.readInt();
386 ledOnMS = parcel.readInt();
387 ledOffMS = parcel.readInt();
388 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400389
390 if (parcel.readInt() != 0) {
391 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 }
394
Andy Stadler110988c2010-12-03 14:29:16 -0800395 @Override
Joe Onorato18e69df2010-05-17 22:26:12 -0700396 public Notification clone() {
397 Notification that = new Notification();
398
399 that.when = this.when;
400 that.icon = this.icon;
401 that.number = this.number;
402
403 // PendingIntents are global, so there's no reason (or way) to clone them.
404 that.contentIntent = this.contentIntent;
405 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400406 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700407
408 if (this.tickerText != null) {
409 that.tickerText = this.tickerText.toString();
410 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800411 if (this.tickerView != null) {
412 that.tickerView = this.tickerView.clone();
Joe Onoratoef1e7762010-09-17 18:38:38 -0400413 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700414 if (this.contentView != null) {
415 that.contentView = this.contentView.clone();
416 }
Joe Onorato561d3852010-11-20 18:09:34 -0800417 if (this.largeIcon != null) {
418 that.largeIcon = Bitmap.createBitmap(this.largeIcon);
419 }
Jozef BABJAKa8b91832011-02-22 08:05:08 +0100420 that.iconLevel = this.iconLevel;
Joe Onorato18e69df2010-05-17 22:26:12 -0700421 that.sound = this.sound; // android.net.Uri is immutable
422 that.audioStreamType = this.audioStreamType;
423
424 final long[] vibrate = this.vibrate;
425 if (vibrate != null) {
426 final int N = vibrate.length;
427 final long[] vib = that.vibrate = new long[N];
428 System.arraycopy(vibrate, 0, vib, 0, N);
429 }
430
431 that.ledARGB = this.ledARGB;
432 that.ledOnMS = this.ledOnMS;
433 that.ledOffMS = this.ledOffMS;
434 that.defaults = this.defaults;
435
436 that.flags = this.flags;
437
438 return that;
439 }
440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 public int describeContents() {
442 return 0;
443 }
444
445 /**
446 * Flatten this notification from a parcel.
447 */
448 public void writeToParcel(Parcel parcel, int flags)
449 {
450 parcel.writeInt(1);
451
452 parcel.writeLong(when);
453 parcel.writeInt(icon);
454 parcel.writeInt(number);
455 if (contentIntent != null) {
456 parcel.writeInt(1);
457 contentIntent.writeToParcel(parcel, 0);
458 } else {
459 parcel.writeInt(0);
460 }
461 if (deleteIntent != null) {
462 parcel.writeInt(1);
463 deleteIntent.writeToParcel(parcel, 0);
464 } else {
465 parcel.writeInt(0);
466 }
467 if (tickerText != null) {
468 parcel.writeInt(1);
469 TextUtils.writeToParcel(tickerText, parcel, flags);
470 } else {
471 parcel.writeInt(0);
472 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800473 if (tickerView != null) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400474 parcel.writeInt(1);
Joe Onorato46439ce2010-11-19 13:56:21 -0800475 tickerView.writeToParcel(parcel, 0);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400476 } else {
477 parcel.writeInt(0);
478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 if (contentView != null) {
480 parcel.writeInt(1);
481 contentView.writeToParcel(parcel, 0);
482 } else {
483 parcel.writeInt(0);
484 }
Joe Onorato561d3852010-11-20 18:09:34 -0800485 if (largeIcon != null) {
486 parcel.writeInt(1);
487 largeIcon.writeToParcel(parcel, 0);
488 } else {
489 parcel.writeInt(0);
490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491
492 parcel.writeInt(defaults);
493 parcel.writeInt(this.flags);
494
495 if (sound != null) {
496 parcel.writeInt(1);
497 sound.writeToParcel(parcel, 0);
498 } else {
499 parcel.writeInt(0);
500 }
501 parcel.writeInt(audioStreamType);
502 parcel.writeLongArray(vibrate);
503 parcel.writeInt(ledARGB);
504 parcel.writeInt(ledOnMS);
505 parcel.writeInt(ledOffMS);
506 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400507
508 if (fullScreenIntent != null) {
509 parcel.writeInt(1);
510 fullScreenIntent.writeToParcel(parcel, 0);
511 } else {
512 parcel.writeInt(0);
513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 }
515
516 /**
517 * Parcelable.Creator that instantiates Notification objects
518 */
519 public static final Parcelable.Creator<Notification> CREATOR
520 = new Parcelable.Creator<Notification>()
521 {
522 public Notification createFromParcel(Parcel parcel)
523 {
524 return new Notification(parcel);
525 }
526
527 public Notification[] newArray(int size)
528 {
529 return new Notification[size];
530 }
531 };
532
533 /**
534 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
535 * layout.
536 *
537 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
538 * in the view.</p>
539 * @param context The context for your application / activity.
540 * @param contentTitle The title that goes in the expanded entry.
541 * @param contentText The text that goes in the expanded entry.
542 * @param contentIntent The intent to launch when the user clicks the expanded notification.
543 * If this is an activity, it must include the
544 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800545 * that you take care of task management as described in the
546 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
547 * Stack</a> document.
Joe Onorato46439ce2010-11-19 13:56:21 -0800548 *
549 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800551 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 public void setLatestEventInfo(Context context,
553 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
554 RemoteViews contentView = new RemoteViews(context.getPackageName(),
Joe Onorato561d3852010-11-20 18:09:34 -0800555 R.layout.status_bar_latest_event_content);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 if (this.icon != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800557 contentView.setImageViewResource(R.id.icon, this.icon);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 }
559 if (contentTitle != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800560 contentView.setTextViewText(R.id.title, contentTitle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 }
562 if (contentText != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800563 contentView.setTextViewText(R.id.text, contentText);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 }
565 if (this.when != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800566 contentView.setLong(R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 }
568
569 this.contentView = contentView;
570 this.contentIntent = contentIntent;
571 }
572
573 @Override
574 public String toString() {
575 StringBuilder sb = new StringBuilder();
Joe Onoratoc9596d62011-01-12 17:03:11 -0800576 sb.append("Notification(contentView=");
577 if (contentView != null) {
578 sb.append(contentView.getPackage());
579 sb.append("/0x");
580 sb.append(Integer.toHexString(contentView.getLayoutId()));
581 } else {
582 sb.append("null");
583 }
584 sb.append(" vibrate=");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 if (this.vibrate != null) {
586 int N = this.vibrate.length-1;
587 sb.append("[");
588 for (int i=0; i<N; i++) {
589 sb.append(this.vibrate[i]);
590 sb.append(',');
591 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200592 if (N != -1) {
593 sb.append(this.vibrate[N]);
594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 sb.append("]");
596 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
597 sb.append("default");
598 } else {
599 sb.append("null");
600 }
601 sb.append(",sound=");
602 if (this.sound != null) {
603 sb.append(this.sound.toString());
604 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
605 sb.append("default");
606 } else {
607 sb.append("null");
608 }
609 sb.append(",defaults=0x");
610 sb.append(Integer.toHexString(this.defaults));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400611 sb.append(",flags=0x");
612 sb.append(Integer.toHexString(this.flags));
613 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
614 sb.append("!!!1!one!");
615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 sb.append(")");
617 return sb.toString();
618 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800619
Joe Onoratocb109a02011-01-18 17:57:41 -0800620 /**
621 * Builder class for {@link Notification} objects. Allows easier control over
622 * all the flags, as well as help constructing the typical notification layouts.
623 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800624 public static class Builder {
625 private Context mContext;
626
627 private long mWhen;
628 private int mSmallIcon;
629 private int mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800630 private int mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800631 private CharSequence mContentTitle;
632 private CharSequence mContentText;
633 private CharSequence mContentInfo;
634 private PendingIntent mContentIntent;
635 private RemoteViews mContentView;
636 private PendingIntent mDeleteIntent;
637 private PendingIntent mFullScreenIntent;
638 private CharSequence mTickerText;
639 private RemoteViews mTickerView;
640 private Bitmap mLargeIcon;
641 private Uri mSound;
642 private int mAudioStreamType;
643 private long[] mVibrate;
644 private int mLedArgb;
645 private int mLedOnMs;
646 private int mLedOffMs;
647 private int mDefaults;
648 private int mFlags;
Jeff Sharkey1c400132011-08-05 14:50:13 -0700649 private int mProgressMax;
650 private int mProgress;
651 private boolean mProgressIndeterminate;
Joe Onorato46439ce2010-11-19 13:56:21 -0800652
Joe Onoratocb109a02011-01-18 17:57:41 -0800653 /**
654 * Constructor.
655 *
656 * Automatically sets the when field to {@link System#currentTimeMillis()
657 * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
658 *
659 * @param context A {@link Context} that will be used to construct the
660 * RemoteViews. The Context will not be held past the lifetime of this
661 * Builder object.
662 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800663 public Builder(Context context) {
664 mContext = context;
Andy Stadler110988c2010-12-03 14:29:16 -0800665
666 // Set defaults to match the defaults of a Notification
Joe Onorato46439ce2010-11-19 13:56:21 -0800667 mWhen = System.currentTimeMillis();
Andy Stadler110988c2010-12-03 14:29:16 -0800668 mAudioStreamType = STREAM_DEFAULT;
Joe Onorato46439ce2010-11-19 13:56:21 -0800669 }
670
Joe Onoratocb109a02011-01-18 17:57:41 -0800671 /**
672 * Set the time that the event occurred. Notifications in the panel are
673 * sorted by this time.
674 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800675 public Builder setWhen(long when) {
676 mWhen = when;
677 return this;
678 }
679
Joe Onoratocb109a02011-01-18 17:57:41 -0800680 /**
681 * Set the small icon to use in the notification layouts. Different classes of devices
682 * may return different sizes. See the UX guidelines for more information on how to
683 * design these icons.
684 *
685 * @param icon A resource ID in the application's package of the drawble to use.
686 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800687 public Builder setSmallIcon(int icon) {
688 mSmallIcon = icon;
689 return this;
690 }
691
Joe Onoratocb109a02011-01-18 17:57:41 -0800692 /**
693 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
694 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
695 * LevelListDrawable}.
696 *
697 * @param icon A resource ID in the application's package of the drawble to use.
698 * @param level The level to use for the icon.
699 *
700 * @see android.graphics.drawable.LevelListDrawable
701 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800702 public Builder setSmallIcon(int icon, int level) {
703 mSmallIcon = icon;
704 mSmallIconLevel = level;
705 return this;
706 }
707
Joe Onoratocb109a02011-01-18 17:57:41 -0800708 /**
709 * Set the title (first row) of the notification, in a standard notification.
710 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800711 public Builder setContentTitle(CharSequence title) {
712 mContentTitle = title;
713 return this;
714 }
715
Joe Onoratocb109a02011-01-18 17:57:41 -0800716 /**
717 * Set the text (second row) of the notification, in a standard notification.
718 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800719 public Builder setContentText(CharSequence text) {
720 mContentText = text;
721 return this;
722 }
723
Joe Onoratocb109a02011-01-18 17:57:41 -0800724 /**
725 * Set the large number at the right-hand side of the notification. This is
726 * equivalent to setContentInfo, although it might show the number in a different
727 * font size for readability.
728 */
Joe Onorato8595a3d2010-11-19 18:12:07 -0800729 public Builder setNumber(int number) {
730 mNumber = number;
731 return this;
732 }
733
Joe Onoratocb109a02011-01-18 17:57:41 -0800734 /**
735 * Set the large text at the right-hand side of the notification.
736 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800737 public Builder setContentInfo(CharSequence info) {
738 mContentInfo = info;
739 return this;
740 }
741
Joe Onoratocb109a02011-01-18 17:57:41 -0800742 /**
Jeff Sharkey1c400132011-08-05 14:50:13 -0700743 * Set the progress this notification represents, which may be
744 * represented as a {@link ProgressBar}.
745 */
746 public Builder setProgress(int max, int progress, boolean indeterminate) {
747 mProgressMax = max;
748 mProgress = progress;
749 mProgressIndeterminate = indeterminate;
750 return this;
751 }
752
753 /**
Joe Onoratocb109a02011-01-18 17:57:41 -0800754 * Supply a custom RemoteViews to use instead of the standard one.
755 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800756 public Builder setContent(RemoteViews views) {
757 mContentView = views;
758 return this;
759 }
760
Joe Onoratocb109a02011-01-18 17:57:41 -0800761 /**
762 * Supply a {@link PendingIntent} to send when the notification is clicked.
763 * If you do not supply an intent, you can now add PendingIntents to individual
764 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
765 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
766 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800767 public Builder setContentIntent(PendingIntent intent) {
768 mContentIntent = intent;
769 return this;
770 }
771
Joe Onoratocb109a02011-01-18 17:57:41 -0800772 /**
773 * Supply a {@link PendingIntent} to send when the notification is cleared by the user
774 * directly from the notification panel. For example, this intent is sent when the user
775 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
776 * intent is not sent when the application calls {@link NotificationManager#cancel
777 * NotificationManager.cancel(int)}.
778 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800779 public Builder setDeleteIntent(PendingIntent intent) {
780 mDeleteIntent = intent;
781 return this;
782 }
783
Joe Onoratocb109a02011-01-18 17:57:41 -0800784 /**
785 * An intent to launch instead of posting the notification to the status bar.
786 * Only for use with extremely high-priority notifications demanding the user's
787 * <strong>immediate</strong> attention, such as an incoming phone call or
788 * alarm clock that the user has explicitly set to a particular time.
789 * If this facility is used for something else, please give the user an option
790 * to turn it off and use a normal notification, as this can be extremely
791 * disruptive.
792 *
793 * @param intent The pending intent to launch.
794 * @param highPriority Passing true will cause this notification to be sent
795 * even if other notifications are suppressed.
796 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800797 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
798 mFullScreenIntent = intent;
799 setFlag(FLAG_HIGH_PRIORITY, highPriority);
800 return this;
801 }
802
Joe Onoratocb109a02011-01-18 17:57:41 -0800803 /**
804 * Set the text that is displayed in the status bar when the notification first
805 * arrives.
806 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800807 public Builder setTicker(CharSequence tickerText) {
808 mTickerText = tickerText;
809 return this;
810 }
811
Joe Onoratocb109a02011-01-18 17:57:41 -0800812 /**
813 * Set the text that is displayed in the status bar when the notification first
814 * arrives, and also a RemoteViews object that may be displayed instead on some
815 * devices.
816 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800817 public Builder setTicker(CharSequence tickerText, RemoteViews views) {
818 mTickerText = tickerText;
819 mTickerView = views;
820 return this;
821 }
822
Joe Onoratocb109a02011-01-18 17:57:41 -0800823 /**
824 * Set the large icon that is shown in the ticker and notification.
825 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800826 public Builder setLargeIcon(Bitmap icon) {
827 mLargeIcon = icon;
828 return this;
829 }
830
Joe Onoratocb109a02011-01-18 17:57:41 -0800831 /**
832 * Set the sound to play. It will play on the default stream.
833 */
Joe Onorato52f80cd2010-11-21 15:34:48 -0800834 public Builder setSound(Uri sound) {
835 mSound = sound;
836 mAudioStreamType = STREAM_DEFAULT;
837 return this;
838 }
839
Joe Onoratocb109a02011-01-18 17:57:41 -0800840 /**
841 * Set the sound to play. It will play on the stream you supply.
842 *
843 * @see #STREAM_DEFAULT
844 * @see AudioManager for the <code>STREAM_</code> constants.
845 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800846 public Builder setSound(Uri sound, int streamType) {
847 mSound = sound;
848 mAudioStreamType = streamType;
849 return this;
850 }
851
Joe Onoratocb109a02011-01-18 17:57:41 -0800852 /**
853 * Set the vibration pattern to use.
854 *
855 * @see android.os.Vibrator for a discussion of the <code>pattern</code>
856 * parameter.
857 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800858 public Builder setVibrate(long[] pattern) {
859 mVibrate = pattern;
860 return this;
861 }
862
Joe Onoratocb109a02011-01-18 17:57:41 -0800863 /**
864 * Set the argb value that you would like the LED on the device to blnk, as well as the
865 * rate. The rate is specified in terms of the number of milliseconds to be on
866 * and then the number of milliseconds to be off.
867 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800868 public Builder setLights(int argb, int onMs, int offMs) {
869 mLedArgb = argb;
870 mLedOnMs = onMs;
871 mLedOffMs = offMs;
Joe Onorato46439ce2010-11-19 13:56:21 -0800872 return this;
873 }
874
Joe Onoratocb109a02011-01-18 17:57:41 -0800875 /**
876 * Set whether this is an ongoing notification.
877 *
878 * <p>Ongoing notifications differ from regular notifications in the following ways:
879 * <ul>
880 * <li>Ongoing notifications are sorted above the regular notifications in the
881 * notification panel.</li>
882 * <li>Ongoing notifications do not have an 'X' close button, and are not affected
883 * by the "Clear all" button.
884 * </ul>
885 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800886 public Builder setOngoing(boolean ongoing) {
887 setFlag(FLAG_ONGOING_EVENT, ongoing);
888 return this;
889 }
890
Joe Onoratocb109a02011-01-18 17:57:41 -0800891 /**
892 * Set this flag if you would only like the sound, vibrate
893 * and ticker to be played if the notification is not already showing.
894 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800895 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
896 setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
897 return this;
898 }
899
Joe Onoratocb109a02011-01-18 17:57:41 -0800900 /**
901 * Setting this flag will make it so the notification is automatically
902 * canceled when the user clicks it in the panel. The PendingIntent
903 * set with {@link #setDeleteIntent} will be broadcast when the notification
904 * is canceled.
905 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800906 public Builder setAutoCancel(boolean autoCancel) {
Joe Onorato281d83f2011-01-04 17:13:10 -0800907 setFlag(FLAG_AUTO_CANCEL, autoCancel);
Joe Onorato46439ce2010-11-19 13:56:21 -0800908 return this;
909 }
910
Joe Onoratocb109a02011-01-18 17:57:41 -0800911 /**
912 * Set the default notification options that will be used.
913 * <p>
914 * The value should be one or more of the following fields combined with
915 * bitwise-or:
916 * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
917 * <p>
918 * For all default values, use {@link #DEFAULT_ALL}.
919 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800920 public Builder setDefaults(int defaults) {
921 mDefaults = defaults;
922 return this;
923 }
924
925 private void setFlag(int mask, boolean value) {
926 if (value) {
927 mFlags |= mask;
928 } else {
929 mFlags &= ~mask;
930 }
931 }
932
Joe Onorato561d3852010-11-20 18:09:34 -0800933 private RemoteViews makeRemoteViews(int resId) {
934 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
Jeff Sharkey1c400132011-08-05 14:50:13 -0700935 boolean hasLine3 = false;
Joe Onorato561d3852010-11-20 18:09:34 -0800936 if (mSmallIcon != 0) {
937 contentView.setImageViewResource(R.id.icon, mSmallIcon);
Jeff Sharkey1c400132011-08-05 14:50:13 -0700938 contentView.setViewVisibility(R.id.icon, View.VISIBLE);
939 } else {
940 contentView.setViewVisibility(R.id.icon, View.GONE);
Joe Onorato561d3852010-11-20 18:09:34 -0800941 }
942 if (mContentTitle != null) {
943 contentView.setTextViewText(R.id.title, mContentTitle);
944 }
945 if (mContentText != null) {
946 contentView.setTextViewText(R.id.text, mContentText);
Jeff Sharkey1c400132011-08-05 14:50:13 -0700947 hasLine3 = true;
Joe Onorato561d3852010-11-20 18:09:34 -0800948 }
949 if (mContentInfo != null) {
950 contentView.setTextViewText(R.id.info, mContentInfo);
Jeff Sharkey1c400132011-08-05 14:50:13 -0700951 contentView.setViewVisibility(R.id.info, View.VISIBLE);
952 hasLine3 = true;
Joe Onorato561d3852010-11-20 18:09:34 -0800953 } else if (mNumber > 0) {
Daniel Sandlerebce0112011-06-16 16:44:51 -0400954 final int tooBig = mContext.getResources().getInteger(
955 R.integer.status_bar_notification_info_maxnum);
956 if (mNumber > tooBig) {
957 contentView.setTextViewText(R.id.info, mContext.getResources().getString(
958 R.string.status_bar_notification_info_overflow));
Joe Onorato059a2f82011-01-04 10:27:01 -0800959 } else {
960 NumberFormat f = NumberFormat.getIntegerInstance();
961 contentView.setTextViewText(R.id.info, f.format(mNumber));
962 }
Jeff Sharkey1c400132011-08-05 14:50:13 -0700963 contentView.setViewVisibility(R.id.info, View.VISIBLE);
964 hasLine3 = true;
Joe Onorato561d3852010-11-20 18:09:34 -0800965 } else {
966 contentView.setViewVisibility(R.id.info, View.GONE);
967 }
Jeff Sharkey1c400132011-08-05 14:50:13 -0700968 if (mProgressMax != 0 || mProgressIndeterminate) {
969 contentView.setProgressBar(
970 R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
971 contentView.setViewVisibility(R.id.progress, View.VISIBLE);
972 } else {
973 contentView.setViewVisibility(R.id.progress, View.GONE);
974 }
Joe Onorato561d3852010-11-20 18:09:34 -0800975 if (mWhen != 0) {
976 contentView.setLong(R.id.time, "setTime", mWhen);
977 }
Jeff Sharkey1c400132011-08-05 14:50:13 -0700978 contentView.setViewVisibility(R.id.line3, hasLine3 ? View.VISIBLE : View.GONE);
Joe Onorato561d3852010-11-20 18:09:34 -0800979 return contentView;
980 }
981
Joe Onorato46439ce2010-11-19 13:56:21 -0800982 private RemoteViews makeContentView() {
983 if (mContentView != null) {
984 return mContentView;
985 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800986 return makeRemoteViews(mLargeIcon == null
987 ? R.layout.status_bar_latest_event_content
988 : R.layout.status_bar_latest_event_content_large_icon);
Joe Onorato46439ce2010-11-19 13:56:21 -0800989 }
990 }
991
992 private RemoteViews makeTickerView() {
993 if (mTickerView != null) {
994 return mTickerView;
995 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800996 if (mContentView == null) {
997 return makeRemoteViews(mLargeIcon == null
998 ? R.layout.status_bar_latest_event_ticker
999 : R.layout.status_bar_latest_event_ticker_large_icon);
1000 } else {
1001 return null;
1002 }
Joe Onorato46439ce2010-11-19 13:56:21 -08001003 }
1004 }
1005
Joe Onoratocb109a02011-01-18 17:57:41 -08001006 /**
1007 * Combine all of the options that have been set and return a new {@link Notification}
1008 * object.
1009 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001010 public Notification getNotification() {
1011 Notification n = new Notification();
1012 n.when = mWhen;
1013 n.icon = mSmallIcon;
1014 n.iconLevel = mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -08001015 n.number = mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -08001016 n.contentView = makeContentView();
1017 n.contentIntent = mContentIntent;
1018 n.deleteIntent = mDeleteIntent;
1019 n.fullScreenIntent = mFullScreenIntent;
1020 n.tickerText = mTickerText;
1021 n.tickerView = makeTickerView();
1022 n.largeIcon = mLargeIcon;
1023 n.sound = mSound;
1024 n.audioStreamType = mAudioStreamType;
1025 n.vibrate = mVibrate;
1026 n.ledARGB = mLedArgb;
1027 n.ledOnMS = mLedOnMs;
1028 n.ledOffMS = mLedOffMs;
1029 n.defaults = mDefaults;
1030 n.flags = mFlags;
Joe Onorato8d0b6552010-11-22 16:09:29 -08001031 if (mLedOnMs != 0 && mLedOffMs != 0) {
1032 n.flags |= FLAG_SHOW_LIGHTS;
1033 }
1034 if ((mDefaults & DEFAULT_LIGHTS) != 0) {
1035 n.flags |= FLAG_SHOW_LIGHTS;
1036 }
Joe Onorato46439ce2010-11-19 13:56:21 -08001037 return n;
1038 }
1039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040}