blob: c9351affc1e2c49c92f3c5dd2f8fb8903d5c21c4 [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.widget.RemoteViews;
30
Andy Stadler110988c2010-12-03 14:29:16 -080031import java.text.NumberFormat;
Joe Onorato561d3852010-11-20 18:09:34 -080032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033/**
34 * A class that represents how a persistent notification is to be presented to
35 * the user using the {@link android.app.NotificationManager}.
36 *
Joe Onoratocb109a02011-01-18 17:57:41 -080037 * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
38 * easier to construct Notifications.</p>
39 *
Scott Mainb8b36452009-04-26 15:50:49 -070040 * <p>For a guide to creating notifications, see the
41 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
42 * Bar Notifications</a> document in the Dev Guide.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 */
44public class Notification implements Parcelable
45{
46 /**
47 * Use all default values (where applicable).
48 */
49 public static final int DEFAULT_ALL = ~0;
50
51 /**
52 * Use the default notification sound. This will ignore any given
53 * {@link #sound}.
54 *
55 * @see #defaults
56 */
57 public static final int DEFAULT_SOUND = 1;
58
59 /**
60 * Use the default notification vibrate. This will ignore any given
Scott Mainb8b36452009-04-26 15:50:49 -070061 * {@link #vibrate}. Using phone vibration requires the
62 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 *
64 * @see #defaults
65 */
66 public static final int DEFAULT_VIBRATE = 2;
67
68 /**
69 * Use the default notification lights. This will ignore the
70 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
71 * {@link #ledOnMS}.
72 *
73 * @see #defaults
74 */
75 public static final int DEFAULT_LIGHTS = 4;
76
77 /**
78 * The timestamp for the notification. The icons and expanded views
79 * are sorted by this key.
80 */
81 public long when;
82
83 /**
84 * The resource id of a drawable to use as the icon in the status bar.
Daniel Sandlerd952dae2011-02-07 16:33:36 -050085 * This is required; notifications with an invalid icon resource will not be shown.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 */
87 public int icon;
88
89 /**
Joe Onorato46439ce2010-11-19 13:56:21 -080090 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
91 * leave it at its default value of 0.
92 *
93 * @see android.widget.ImageView#setImageLevel
94 * @see android.graphics.drawable#setLevel
95 */
96 public int iconLevel;
97
98 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -040099 * The number of events that this notification represents. For example, in a new mail
100 * notification, this could be the number of unread messages. This number is superimposed over
101 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
102 * bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 */
104 public int number;
105
106 /**
107 * The intent to execute when the expanded status entry is clicked. If
108 * this is an activity, it must include the
109 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800110 * that you take care of task management as described in the
111 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
112 * Stack</a> document.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 */
114 public PendingIntent contentIntent;
115
116 /**
117 * The intent to execute when the status entry is deleted by the user
118 * with the "Clear All Notifications" button. This probably shouldn't
119 * be launching an activity since several of those will be sent at the
120 * same time.
121 */
122 public PendingIntent deleteIntent;
123
124 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700125 * An intent to launch instead of posting the notification to the status bar.
Joe Onoratocb109a02011-01-18 17:57:41 -0800126 *
127 * @see Notification.Builder#setFullScreenIntent
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400128 */
129 public PendingIntent fullScreenIntent;
130
131 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 * Text to scroll across the screen when this item is added to
Joe Onoratoef1e7762010-09-17 18:38:38 -0400133 * the status bar on large and smaller devices.
134 *
135 * <p>This field is provided separately from the other ticker fields
136 * both for compatibility and to allow an application to choose different
137 * text for when the text scrolls in and when it is displayed all at once
138 * in conjunction with one or more icons.
139 *
Joe Onorato46439ce2010-11-19 13:56:21 -0800140 * @see #tickerView
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 */
142 public CharSequence tickerText;
143
144 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800145 * The view to show as the ticker in the status bar when the notification
146 * is posted.
Joe Onoratoef1e7762010-09-17 18:38:38 -0400147 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800148 public RemoteViews tickerView;
Joe Onoratoef1e7762010-09-17 18:38:38 -0400149
150 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400151 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 */
153 public RemoteViews contentView;
154
155 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800156 * The bitmap that may escape the bounds of the panel and bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800158 public Bitmap largeIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159
160 /**
161 * The sound to play.
162 *
163 * <p>
164 * To play the default notification sound, see {@link #defaults}.
165 * </p>
166 */
167 public Uri sound;
168
169 /**
170 * Use this constant as the value for audioStreamType to request that
171 * the default stream type for notifications be used. Currently the
172 * default stream type is STREAM_RING.
173 */
174 public static final int STREAM_DEFAULT = -1;
175
176 /**
177 * The audio stream type to use when playing the sound.
178 * Should be one of the STREAM_ constants from
179 * {@link android.media.AudioManager}.
180 */
181 public int audioStreamType = STREAM_DEFAULT;
182
183
184 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700185 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 *
187 * <p>
188 * To vibrate the default pattern, see {@link #defaults}.
189 * </p>
190 *
191 * @see android.os.Vibrator#vibrate(long[],int)
192 */
193 public long[] vibrate;
194
195 /**
196 * The color of the led. The hardware will do its best approximation.
197 *
198 * @see #FLAG_SHOW_LIGHTS
199 * @see #flags
200 */
201 public int ledARGB;
202
203 /**
204 * The number of milliseconds for the LED to be on while it's flashing.
205 * The hardware will do its best approximation.
206 *
207 * @see #FLAG_SHOW_LIGHTS
208 * @see #flags
209 */
210 public int ledOnMS;
211
212 /**
213 * The number of milliseconds for the LED to be off while it's flashing.
214 * The hardware will do its best approximation.
215 *
216 * @see #FLAG_SHOW_LIGHTS
217 * @see #flags
218 */
219 public int ledOffMS;
220
221 /**
222 * Specifies which values should be taken from the defaults.
223 * <p>
224 * To set, OR the desired from {@link #DEFAULT_SOUND},
225 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
226 * values, use {@link #DEFAULT_ALL}.
227 * </p>
228 */
229 public int defaults;
230
231
232 /**
233 * Bit to be bitwise-ored into the {@link #flags} field that should be
234 * set if you want the LED on for this notification.
235 * <ul>
236 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
237 * or 0 for both ledOnMS and ledOffMS.</li>
238 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
239 * <li>To flash the LED, pass the number of milliseconds that it should
240 * be on and off to ledOnMS and ledOffMS.</li>
241 * </ul>
242 * <p>
243 * Since hardware varies, you are not guaranteed that any of the values
244 * you pass are honored exactly. Use the system defaults (TODO) if possible
245 * because they will be set to values that work on any given hardware.
246 * <p>
247 * The alpha channel must be set for forward compatibility.
248 *
249 */
250 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
251
252 /**
253 * Bit to be bitwise-ored into the {@link #flags} field that should be
254 * set if this notification is in reference to something that is ongoing,
255 * like a phone call. It should not be set if this notification is in
256 * reference to something that happened at a particular point in time,
257 * like a missed phone call.
258 */
259 public static final int FLAG_ONGOING_EVENT = 0x00000002;
260
261 /**
262 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700263 * the audio will be repeated until the notification is
264 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 */
266 public static final int FLAG_INSISTENT = 0x00000004;
267
268 /**
269 * Bit to be bitwise-ored into the {@link #flags} field that should be
270 * set if you want the sound and/or vibration play each time the
271 * notification is sent, even if it has not been canceled before that.
272 */
273 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
274
275 /**
276 * Bit to be bitwise-ored into the {@link #flags} field that should be
277 * set if the notification should be canceled when it is clicked by the
Joe Onoratocb109a02011-01-18 17:57:41 -0800278 * user. On tablets, the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 */
280 public static final int FLAG_AUTO_CANCEL = 0x00000010;
281
282 /**
283 * Bit to be bitwise-ored into the {@link #flags} field that should be
284 * set if the notification should not be canceled when the user clicks
285 * the Clear all button.
286 */
287 public static final int FLAG_NO_CLEAR = 0x00000020;
288
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700289 /**
290 * Bit to be bitwise-ored into the {@link #flags} field that should be
291 * set if this notification represents a currently running service. This
292 * will normally be set for you by {@link Service#startForeground}.
293 */
294 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
295
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400296 /**
297 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
298 * represents a high-priority event that may be shown to the user even if notifications are
299 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
300 * in conjunction with {@link #fullScreenIntent}.
301 */
302 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 public int flags;
305
306 /**
307 * Constructs a Notification object with everything set to 0.
Joe Onorato46439ce2010-11-19 13:56:21 -0800308 * You might want to consider using {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 */
310 public Notification()
311 {
312 this.when = System.currentTimeMillis();
313 }
314
315 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 * @hide
317 */
318 public Notification(Context context, int icon, CharSequence tickerText, long when,
319 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
320 {
321 this.when = when;
322 this.icon = icon;
323 this.tickerText = tickerText;
324 setLatestEventInfo(context, contentTitle, contentText,
325 PendingIntent.getActivity(context, 0, contentIntent, 0));
326 }
327
328 /**
329 * Constructs a Notification object with the information needed to
330 * have a status bar icon without the standard expanded view.
331 *
332 * @param icon The resource id of the icon to put in the status bar.
333 * @param tickerText The text that flows by in the status bar when the notification first
334 * activates.
335 * @param when The time to show in the time field. In the System.currentTimeMillis
336 * timebase.
Joe Onorato46439ce2010-11-19 13:56:21 -0800337 *
338 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800340 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 public Notification(int icon, CharSequence tickerText, long when)
342 {
343 this.icon = icon;
344 this.tickerText = tickerText;
345 this.when = when;
346 }
347
348 /**
349 * Unflatten the notification from a parcel.
350 */
351 public Notification(Parcel parcel)
352 {
353 int version = parcel.readInt();
354
355 when = parcel.readLong();
356 icon = parcel.readInt();
357 number = parcel.readInt();
358 if (parcel.readInt() != 0) {
359 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
360 }
361 if (parcel.readInt() != 0) {
362 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
363 }
364 if (parcel.readInt() != 0) {
365 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
366 }
367 if (parcel.readInt() != 0) {
Joe Onorato46439ce2010-11-19 13:56:21 -0800368 tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400369 }
370 if (parcel.readInt() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
372 }
Joe Onorato561d3852010-11-20 18:09:34 -0800373 if (parcel.readInt() != 0) {
374 largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 defaults = parcel.readInt();
377 flags = parcel.readInt();
378 if (parcel.readInt() != 0) {
379 sound = Uri.CREATOR.createFromParcel(parcel);
380 }
381
382 audioStreamType = parcel.readInt();
383 vibrate = parcel.createLongArray();
384 ledARGB = parcel.readInt();
385 ledOnMS = parcel.readInt();
386 ledOffMS = parcel.readInt();
387 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400388
389 if (parcel.readInt() != 0) {
390 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 }
393
Andy Stadler110988c2010-12-03 14:29:16 -0800394 @Override
Joe Onorato18e69df2010-05-17 22:26:12 -0700395 public Notification clone() {
396 Notification that = new Notification();
397
398 that.when = this.when;
399 that.icon = this.icon;
400 that.number = this.number;
401
402 // PendingIntents are global, so there's no reason (or way) to clone them.
403 that.contentIntent = this.contentIntent;
404 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400405 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700406
407 if (this.tickerText != null) {
408 that.tickerText = this.tickerText.toString();
409 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800410 if (this.tickerView != null) {
411 that.tickerView = this.tickerView.clone();
Joe Onoratoef1e7762010-09-17 18:38:38 -0400412 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700413 if (this.contentView != null) {
414 that.contentView = this.contentView.clone();
415 }
Joe Onorato561d3852010-11-20 18:09:34 -0800416 if (this.largeIcon != null) {
417 that.largeIcon = Bitmap.createBitmap(this.largeIcon);
418 }
Jozef BABJAKa8b91832011-02-22 08:05:08 +0100419 that.iconLevel = this.iconLevel;
Joe Onorato18e69df2010-05-17 22:26:12 -0700420 that.sound = this.sound; // android.net.Uri is immutable
421 that.audioStreamType = this.audioStreamType;
422
423 final long[] vibrate = this.vibrate;
424 if (vibrate != null) {
425 final int N = vibrate.length;
426 final long[] vib = that.vibrate = new long[N];
427 System.arraycopy(vibrate, 0, vib, 0, N);
428 }
429
430 that.ledARGB = this.ledARGB;
431 that.ledOnMS = this.ledOnMS;
432 that.ledOffMS = this.ledOffMS;
433 that.defaults = this.defaults;
434
435 that.flags = this.flags;
436
437 return that;
438 }
439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 public int describeContents() {
441 return 0;
442 }
443
444 /**
445 * Flatten this notification from a parcel.
446 */
447 public void writeToParcel(Parcel parcel, int flags)
448 {
449 parcel.writeInt(1);
450
451 parcel.writeLong(when);
452 parcel.writeInt(icon);
453 parcel.writeInt(number);
454 if (contentIntent != null) {
455 parcel.writeInt(1);
456 contentIntent.writeToParcel(parcel, 0);
457 } else {
458 parcel.writeInt(0);
459 }
460 if (deleteIntent != null) {
461 parcel.writeInt(1);
462 deleteIntent.writeToParcel(parcel, 0);
463 } else {
464 parcel.writeInt(0);
465 }
466 if (tickerText != null) {
467 parcel.writeInt(1);
468 TextUtils.writeToParcel(tickerText, parcel, flags);
469 } else {
470 parcel.writeInt(0);
471 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800472 if (tickerView != null) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400473 parcel.writeInt(1);
Joe Onorato46439ce2010-11-19 13:56:21 -0800474 tickerView.writeToParcel(parcel, 0);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400475 } else {
476 parcel.writeInt(0);
477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 if (contentView != null) {
479 parcel.writeInt(1);
480 contentView.writeToParcel(parcel, 0);
481 } else {
482 parcel.writeInt(0);
483 }
Joe Onorato561d3852010-11-20 18:09:34 -0800484 if (largeIcon != null) {
485 parcel.writeInt(1);
486 largeIcon.writeToParcel(parcel, 0);
487 } else {
488 parcel.writeInt(0);
489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490
491 parcel.writeInt(defaults);
492 parcel.writeInt(this.flags);
493
494 if (sound != null) {
495 parcel.writeInt(1);
496 sound.writeToParcel(parcel, 0);
497 } else {
498 parcel.writeInt(0);
499 }
500 parcel.writeInt(audioStreamType);
501 parcel.writeLongArray(vibrate);
502 parcel.writeInt(ledARGB);
503 parcel.writeInt(ledOnMS);
504 parcel.writeInt(ledOffMS);
505 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400506
507 if (fullScreenIntent != null) {
508 parcel.writeInt(1);
509 fullScreenIntent.writeToParcel(parcel, 0);
510 } else {
511 parcel.writeInt(0);
512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 }
514
515 /**
516 * Parcelable.Creator that instantiates Notification objects
517 */
518 public static final Parcelable.Creator<Notification> CREATOR
519 = new Parcelable.Creator<Notification>()
520 {
521 public Notification createFromParcel(Parcel parcel)
522 {
523 return new Notification(parcel);
524 }
525
526 public Notification[] newArray(int size)
527 {
528 return new Notification[size];
529 }
530 };
531
532 /**
533 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
534 * layout.
535 *
536 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
537 * in the view.</p>
538 * @param context The context for your application / activity.
539 * @param contentTitle The title that goes in the expanded entry.
540 * @param contentText The text that goes in the expanded entry.
541 * @param contentIntent The intent to launch when the user clicks the expanded notification.
542 * If this is an activity, it must include the
543 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800544 * that you take care of task management as described in the
545 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
546 * Stack</a> document.
Joe Onorato46439ce2010-11-19 13:56:21 -0800547 *
548 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800550 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 public void setLatestEventInfo(Context context,
552 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
553 RemoteViews contentView = new RemoteViews(context.getPackageName(),
Joe Onorato561d3852010-11-20 18:09:34 -0800554 R.layout.status_bar_latest_event_content);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 if (this.icon != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800556 contentView.setImageViewResource(R.id.icon, this.icon);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 }
558 if (contentTitle != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800559 contentView.setTextViewText(R.id.title, contentTitle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 }
561 if (contentText != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800562 contentView.setTextViewText(R.id.text, contentText);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 }
564 if (this.when != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800565 contentView.setLong(R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 }
567
568 this.contentView = contentView;
569 this.contentIntent = contentIntent;
570 }
571
572 @Override
573 public String toString() {
574 StringBuilder sb = new StringBuilder();
Joe Onoratoc9596d62011-01-12 17:03:11 -0800575 sb.append("Notification(contentView=");
576 if (contentView != null) {
577 sb.append(contentView.getPackage());
578 sb.append("/0x");
579 sb.append(Integer.toHexString(contentView.getLayoutId()));
580 } else {
581 sb.append("null");
582 }
583 sb.append(" vibrate=");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 if (this.vibrate != null) {
585 int N = this.vibrate.length-1;
586 sb.append("[");
587 for (int i=0; i<N; i++) {
588 sb.append(this.vibrate[i]);
589 sb.append(',');
590 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200591 if (N != -1) {
592 sb.append(this.vibrate[N]);
593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 sb.append("]");
595 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
596 sb.append("default");
597 } else {
598 sb.append("null");
599 }
600 sb.append(",sound=");
601 if (this.sound != null) {
602 sb.append(this.sound.toString());
603 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
604 sb.append("default");
605 } else {
606 sb.append("null");
607 }
608 sb.append(",defaults=0x");
609 sb.append(Integer.toHexString(this.defaults));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400610 sb.append(",flags=0x");
611 sb.append(Integer.toHexString(this.flags));
612 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
613 sb.append("!!!1!one!");
614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 sb.append(")");
616 return sb.toString();
617 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800618
Joe Onoratocb109a02011-01-18 17:57:41 -0800619 /**
620 * Builder class for {@link Notification} objects. Allows easier control over
621 * all the flags, as well as help constructing the typical notification layouts.
622 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800623 public static class Builder {
624 private Context mContext;
625
626 private long mWhen;
627 private int mSmallIcon;
628 private int mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800629 private int mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800630 private CharSequence mContentTitle;
631 private CharSequence mContentText;
632 private CharSequence mContentInfo;
633 private PendingIntent mContentIntent;
634 private RemoteViews mContentView;
635 private PendingIntent mDeleteIntent;
636 private PendingIntent mFullScreenIntent;
637 private CharSequence mTickerText;
638 private RemoteViews mTickerView;
639 private Bitmap mLargeIcon;
640 private Uri mSound;
641 private int mAudioStreamType;
642 private long[] mVibrate;
643 private int mLedArgb;
644 private int mLedOnMs;
645 private int mLedOffMs;
646 private int mDefaults;
647 private int mFlags;
648
Joe Onoratocb109a02011-01-18 17:57:41 -0800649 /**
650 * Constructor.
651 *
652 * Automatically sets the when field to {@link System#currentTimeMillis()
653 * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
654 *
655 * @param context A {@link Context} that will be used to construct the
656 * RemoteViews. The Context will not be held past the lifetime of this
657 * Builder object.
658 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800659 public Builder(Context context) {
660 mContext = context;
Andy Stadler110988c2010-12-03 14:29:16 -0800661
662 // Set defaults to match the defaults of a Notification
Joe Onorato46439ce2010-11-19 13:56:21 -0800663 mWhen = System.currentTimeMillis();
Andy Stadler110988c2010-12-03 14:29:16 -0800664 mAudioStreamType = STREAM_DEFAULT;
Joe Onorato46439ce2010-11-19 13:56:21 -0800665 }
666
Joe Onoratocb109a02011-01-18 17:57:41 -0800667 /**
668 * Set the time that the event occurred. Notifications in the panel are
669 * sorted by this time.
670 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800671 public Builder setWhen(long when) {
672 mWhen = when;
673 return this;
674 }
675
Joe Onoratocb109a02011-01-18 17:57:41 -0800676 /**
677 * Set the small icon to use in the notification layouts. Different classes of devices
678 * may return different sizes. See the UX guidelines for more information on how to
679 * design these icons.
680 *
681 * @param icon A resource ID in the application's package of the drawble to use.
682 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800683 public Builder setSmallIcon(int icon) {
684 mSmallIcon = icon;
685 return this;
686 }
687
Joe Onoratocb109a02011-01-18 17:57:41 -0800688 /**
689 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
690 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
691 * LevelListDrawable}.
692 *
693 * @param icon A resource ID in the application's package of the drawble to use.
694 * @param level The level to use for the icon.
695 *
696 * @see android.graphics.drawable.LevelListDrawable
697 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800698 public Builder setSmallIcon(int icon, int level) {
699 mSmallIcon = icon;
700 mSmallIconLevel = level;
701 return this;
702 }
703
Joe Onoratocb109a02011-01-18 17:57:41 -0800704 /**
705 * Set the title (first row) of the notification, in a standard notification.
706 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800707 public Builder setContentTitle(CharSequence title) {
708 mContentTitle = title;
709 return this;
710 }
711
Joe Onoratocb109a02011-01-18 17:57:41 -0800712 /**
713 * Set the text (second row) of the notification, in a standard notification.
714 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800715 public Builder setContentText(CharSequence text) {
716 mContentText = text;
717 return this;
718 }
719
Joe Onoratocb109a02011-01-18 17:57:41 -0800720 /**
721 * Set the large number at the right-hand side of the notification. This is
722 * equivalent to setContentInfo, although it might show the number in a different
723 * font size for readability.
724 */
Joe Onorato8595a3d2010-11-19 18:12:07 -0800725 public Builder setNumber(int number) {
726 mNumber = number;
727 return this;
728 }
729
Joe Onoratocb109a02011-01-18 17:57:41 -0800730 /**
731 * Set the large text at the right-hand side of the notification.
732 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800733 public Builder setContentInfo(CharSequence info) {
734 mContentInfo = info;
735 return this;
736 }
737
Joe Onoratocb109a02011-01-18 17:57:41 -0800738 /**
739 * Supply a custom RemoteViews to use instead of the standard one.
740 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800741 public Builder setContent(RemoteViews views) {
742 mContentView = views;
743 return this;
744 }
745
Joe Onoratocb109a02011-01-18 17:57:41 -0800746 /**
747 * Supply a {@link PendingIntent} to send when the notification is clicked.
748 * If you do not supply an intent, you can now add PendingIntents to individual
749 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
750 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
751 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800752 public Builder setContentIntent(PendingIntent intent) {
753 mContentIntent = intent;
754 return this;
755 }
756
Joe Onoratocb109a02011-01-18 17:57:41 -0800757 /**
758 * Supply a {@link PendingIntent} to send when the notification is cleared by the user
759 * directly from the notification panel. For example, this intent is sent when the user
760 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
761 * intent is not sent when the application calls {@link NotificationManager#cancel
762 * NotificationManager.cancel(int)}.
763 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800764 public Builder setDeleteIntent(PendingIntent intent) {
765 mDeleteIntent = intent;
766 return this;
767 }
768
Joe Onoratocb109a02011-01-18 17:57:41 -0800769 /**
770 * An intent to launch instead of posting the notification to the status bar.
771 * Only for use with extremely high-priority notifications demanding the user's
772 * <strong>immediate</strong> attention, such as an incoming phone call or
773 * alarm clock that the user has explicitly set to a particular time.
774 * If this facility is used for something else, please give the user an option
775 * to turn it off and use a normal notification, as this can be extremely
776 * disruptive.
777 *
778 * @param intent The pending intent to launch.
779 * @param highPriority Passing true will cause this notification to be sent
780 * even if other notifications are suppressed.
781 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800782 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
783 mFullScreenIntent = intent;
784 setFlag(FLAG_HIGH_PRIORITY, highPriority);
785 return this;
786 }
787
Joe Onoratocb109a02011-01-18 17:57:41 -0800788 /**
789 * Set the text that is displayed in the status bar when the notification first
790 * arrives.
791 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800792 public Builder setTicker(CharSequence tickerText) {
793 mTickerText = tickerText;
794 return this;
795 }
796
Joe Onoratocb109a02011-01-18 17:57:41 -0800797 /**
798 * Set the text that is displayed in the status bar when the notification first
799 * arrives, and also a RemoteViews object that may be displayed instead on some
800 * devices.
801 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800802 public Builder setTicker(CharSequence tickerText, RemoteViews views) {
803 mTickerText = tickerText;
804 mTickerView = views;
805 return this;
806 }
807
Joe Onoratocb109a02011-01-18 17:57:41 -0800808 /**
809 * Set the large icon that is shown in the ticker and notification.
810 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800811 public Builder setLargeIcon(Bitmap icon) {
812 mLargeIcon = icon;
813 return this;
814 }
815
Joe Onoratocb109a02011-01-18 17:57:41 -0800816 /**
817 * Set the sound to play. It will play on the default stream.
818 */
Joe Onorato52f80cd2010-11-21 15:34:48 -0800819 public Builder setSound(Uri sound) {
820 mSound = sound;
821 mAudioStreamType = STREAM_DEFAULT;
822 return this;
823 }
824
Joe Onoratocb109a02011-01-18 17:57:41 -0800825 /**
826 * Set the sound to play. It will play on the stream you supply.
827 *
828 * @see #STREAM_DEFAULT
829 * @see AudioManager for the <code>STREAM_</code> constants.
830 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800831 public Builder setSound(Uri sound, int streamType) {
832 mSound = sound;
833 mAudioStreamType = streamType;
834 return this;
835 }
836
Joe Onoratocb109a02011-01-18 17:57:41 -0800837 /**
838 * Set the vibration pattern to use.
839 *
840 * @see android.os.Vibrator for a discussion of the <code>pattern</code>
841 * parameter.
842 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800843 public Builder setVibrate(long[] pattern) {
844 mVibrate = pattern;
845 return this;
846 }
847
Joe Onoratocb109a02011-01-18 17:57:41 -0800848 /**
849 * Set the argb value that you would like the LED on the device to blnk, as well as the
850 * rate. The rate is specified in terms of the number of milliseconds to be on
851 * and then the number of milliseconds to be off.
852 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800853 public Builder setLights(int argb, int onMs, int offMs) {
854 mLedArgb = argb;
855 mLedOnMs = onMs;
856 mLedOffMs = offMs;
Joe Onorato46439ce2010-11-19 13:56:21 -0800857 return this;
858 }
859
Joe Onoratocb109a02011-01-18 17:57:41 -0800860 /**
861 * Set whether this is an ongoing notification.
862 *
863 * <p>Ongoing notifications differ from regular notifications in the following ways:
864 * <ul>
865 * <li>Ongoing notifications are sorted above the regular notifications in the
866 * notification panel.</li>
867 * <li>Ongoing notifications do not have an 'X' close button, and are not affected
868 * by the "Clear all" button.
869 * </ul>
870 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800871 public Builder setOngoing(boolean ongoing) {
872 setFlag(FLAG_ONGOING_EVENT, ongoing);
873 return this;
874 }
875
Joe Onoratocb109a02011-01-18 17:57:41 -0800876 /**
877 * Set this flag if you would only like the sound, vibrate
878 * and ticker to be played if the notification is not already showing.
879 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800880 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
881 setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
882 return this;
883 }
884
Joe Onoratocb109a02011-01-18 17:57:41 -0800885 /**
886 * Setting this flag will make it so the notification is automatically
887 * canceled when the user clicks it in the panel. The PendingIntent
888 * set with {@link #setDeleteIntent} will be broadcast when the notification
889 * is canceled.
890 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800891 public Builder setAutoCancel(boolean autoCancel) {
Joe Onorato281d83f2011-01-04 17:13:10 -0800892 setFlag(FLAG_AUTO_CANCEL, autoCancel);
Joe Onorato46439ce2010-11-19 13:56:21 -0800893 return this;
894 }
895
Joe Onoratocb109a02011-01-18 17:57:41 -0800896 /**
897 * Set the default notification options that will be used.
898 * <p>
899 * The value should be one or more of the following fields combined with
900 * bitwise-or:
901 * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
902 * <p>
903 * For all default values, use {@link #DEFAULT_ALL}.
904 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800905 public Builder setDefaults(int defaults) {
906 mDefaults = defaults;
907 return this;
908 }
909
910 private void setFlag(int mask, boolean value) {
911 if (value) {
912 mFlags |= mask;
913 } else {
914 mFlags &= ~mask;
915 }
916 }
917
Joe Onorato561d3852010-11-20 18:09:34 -0800918 private RemoteViews makeRemoteViews(int resId) {
919 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
920 if (mSmallIcon != 0) {
921 contentView.setImageViewResource(R.id.icon, mSmallIcon);
922 }
923 if (mContentTitle != null) {
924 contentView.setTextViewText(R.id.title, mContentTitle);
925 }
926 if (mContentText != null) {
927 contentView.setTextViewText(R.id.text, mContentText);
928 }
929 if (mContentInfo != null) {
930 contentView.setTextViewText(R.id.info, mContentInfo);
931 } else if (mNumber > 0) {
Joe Onoratoc6925ca2011-01-28 16:53:13 -0800932 if (mNumber > 999) {
933 contentView.setTextViewText(R.id.info, "999+");
Joe Onorato059a2f82011-01-04 10:27:01 -0800934 } else {
935 NumberFormat f = NumberFormat.getIntegerInstance();
936 contentView.setTextViewText(R.id.info, f.format(mNumber));
937 }
Joe Onorato561d3852010-11-20 18:09:34 -0800938 contentView.setFloat(R.id.info, "setTextSize",
939 mContext.getResources().getDimensionPixelSize(
940 R.dimen.status_bar_content_number_size));
941 } else {
942 contentView.setViewVisibility(R.id.info, View.GONE);
943 }
944 if (mWhen != 0) {
945 contentView.setLong(R.id.time, "setTime", mWhen);
946 }
947 return contentView;
948 }
949
Joe Onorato46439ce2010-11-19 13:56:21 -0800950 private RemoteViews makeContentView() {
951 if (mContentView != null) {
952 return mContentView;
953 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800954 return makeRemoteViews(mLargeIcon == null
955 ? R.layout.status_bar_latest_event_content
956 : R.layout.status_bar_latest_event_content_large_icon);
Joe Onorato46439ce2010-11-19 13:56:21 -0800957 }
958 }
959
960 private RemoteViews makeTickerView() {
961 if (mTickerView != null) {
962 return mTickerView;
963 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800964 if (mContentView == null) {
965 return makeRemoteViews(mLargeIcon == null
966 ? R.layout.status_bar_latest_event_ticker
967 : R.layout.status_bar_latest_event_ticker_large_icon);
968 } else {
969 return null;
970 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800971 }
972 }
973
Joe Onoratocb109a02011-01-18 17:57:41 -0800974 /**
975 * Combine all of the options that have been set and return a new {@link Notification}
976 * object.
977 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800978 public Notification getNotification() {
979 Notification n = new Notification();
980 n.when = mWhen;
981 n.icon = mSmallIcon;
982 n.iconLevel = mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800983 n.number = mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800984 n.contentView = makeContentView();
985 n.contentIntent = mContentIntent;
986 n.deleteIntent = mDeleteIntent;
987 n.fullScreenIntent = mFullScreenIntent;
988 n.tickerText = mTickerText;
989 n.tickerView = makeTickerView();
990 n.largeIcon = mLargeIcon;
991 n.sound = mSound;
992 n.audioStreamType = mAudioStreamType;
993 n.vibrate = mVibrate;
994 n.ledARGB = mLedArgb;
995 n.ledOnMS = mLedOnMs;
996 n.ledOffMS = mLedOffMs;
997 n.defaults = mDefaults;
998 n.flags = mFlags;
Joe Onorato8d0b6552010-11-22 16:09:29 -0800999 if (mLedOnMs != 0 && mLedOffMs != 0) {
1000 n.flags |= FLAG_SHOW_LIGHTS;
1001 }
1002 if ((mDefaults & DEFAULT_LIGHTS) != 0) {
1003 n.flags |= FLAG_SHOW_LIGHTS;
1004 }
Joe Onorato46439ce2010-11-19 13:56:21 -08001005 return n;
1006 }
1007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008}