blob: dc796bf6351f42e1eb3040977d01a94ccc1fc1e7 [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;
Daniel Sandler2561b0b2012-02-13 21:04:12 -050025import android.os.Bundle;
Daniel Sandlera0a938c2012-03-15 08:42:37 -040026import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.os.Parcel;
28import android.os.Parcelable;
Daniel Sandlera2985ed2012-04-03 16:42:00 -040029import android.os.SystemClock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.text.TextUtils;
Daniel Sandlera0a938c2012-03-15 08:42:37 -040031import android.util.IntProperty;
Daniel Sandler96fd7c12012-03-30 16:37:36 -040032import android.util.Log;
Joe Onorato8595a3d2010-11-19 18:12:07 -080033import android.view.View;
Jeff Sharkey1c400132011-08-05 14:50:13 -070034import android.widget.ProgressBar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.widget.RemoteViews;
36
Andy Stadler110988c2010-12-03 14:29:16 -080037import java.text.NumberFormat;
Daniel Sandler2561b0b2012-02-13 21:04:12 -050038import java.util.ArrayList;
Joe Onorato561d3852010-11-20 18:09:34 -080039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040/**
41 * A class that represents how a persistent notification is to be presented to
42 * the user using the {@link android.app.NotificationManager}.
43 *
Joe Onoratocb109a02011-01-18 17:57:41 -080044 * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
45 * easier to construct Notifications.</p>
46 *
Joe Fernandez558459f2011-10-13 16:47:36 -070047 * <div class="special reference">
48 * <h3>Developer Guides</h3>
49 * <p>For a guide to creating notifications, read the
50 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
51 * developer guide.</p>
52 * </div>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 */
54public class Notification implements Parcelable
55{
56 /**
57 * Use all default values (where applicable).
58 */
59 public static final int DEFAULT_ALL = ~0;
Daniel Sandler2561b0b2012-02-13 21:04:12 -050060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 /**
62 * Use the default notification sound. This will ignore any given
63 * {@link #sound}.
Daniel Sandler2561b0b2012-02-13 21:04:12 -050064 *
65
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 * @see #defaults
Daniel Sandler2561b0b2012-02-13 21:04:12 -050067 */
68
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 public static final int DEFAULT_SOUND = 1;
70
71 /**
72 * Use the default notification vibrate. This will ignore any given
Daniel Sandler2561b0b2012-02-13 21:04:12 -050073 * {@link #vibrate}. Using phone vibration requires the
Scott Mainb8b36452009-04-26 15:50:49 -070074 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
Daniel Sandler2561b0b2012-02-13 21:04:12 -050075 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 * @see #defaults
Daniel Sandler2561b0b2012-02-13 21:04:12 -050077 */
78
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 public static final int DEFAULT_VIBRATE = 2;
Daniel Sandler2561b0b2012-02-13 21:04:12 -050080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 /**
82 * Use the default notification lights. This will ignore the
83 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
84 * {@link #ledOnMS}.
Daniel Sandler2561b0b2012-02-13 21:04:12 -050085 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 * @see #defaults
Daniel Sandler2561b0b2012-02-13 21:04:12 -050087 */
88
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 public static final int DEFAULT_LIGHTS = 4;
Daniel Sandler2561b0b2012-02-13 21:04:12 -050090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -050092 * A timestamp related to this notification, in milliseconds since the epoch.
93 *
94 * Default value: {@link System#currentTimeMillis() Now}.
95 *
96 * Choose a timestamp that will be most relevant to the user. For most finite events, this
97 * corresponds to the time the event happened (or will happen, in the case of events that have
98 * yet to occur but about which the user is being informed). Indefinite events should be
99 * timestamped according to when the activity began.
100 *
101 * Some examples:
102 *
103 * <ul>
104 * <li>Notification of a new chat message should be stamped when the message was received.</li>
105 * <li>Notification of an ongoing file download (with a progress bar, for example) should be stamped when the download started.</li>
106 * <li>Notification of a completed file download should be stamped when the download finished.</li>
107 * <li>Notification of an upcoming meeting should be stamped with the time the meeting will begin (that is, in the future).</li>
108 * <li>Notification of an ongoing stopwatch (increasing timer) should be stamped with the watch's start time.
109 * <li>Notification of an ongoing countdown timer should be stamped with the timer's end time.
110 * </ul>
111 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 */
113 public long when;
114
115 /**
116 * The resource id of a drawable to use as the icon in the status bar.
Daniel Sandlerd952dae2011-02-07 16:33:36 -0500117 * This is required; notifications with an invalid icon resource will not be shown.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 */
119 public int icon;
120
121 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800122 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
123 * leave it at its default value of 0.
124 *
125 * @see android.widget.ImageView#setImageLevel
126 * @see android.graphics.drawable#setLevel
127 */
128 public int iconLevel;
129
130 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500131 * The number of events that this notification represents. For example, in a new mail
132 * notification, this could be the number of unread messages.
133 *
134 * The system may or may not use this field to modify the appearance of the notification. For
135 * example, before {@link android.os.Build.VERSION_CODES#HONEYCOMB}, this number was
136 * superimposed over the icon in the status bar. Starting with
137 * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, the template used by
138 * {@link Notification.Builder} has displayed the number in the expanded notification view.
139 *
140 * If the number is 0 or negative, it is never shown.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 */
142 public int number;
143
144 /**
145 * The intent to execute when the expanded status entry is clicked. If
146 * this is an activity, it must include the
147 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800148 * that you take care of task management as described in the
149 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
Dianne Hackborn6ceca582012-01-10 15:24:26 -0800150 * Stack</a> document. In particular, make sure to read the notification section
151 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
152 * Notifications</a> for the correct ways to launch an application from a
153 * notification.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 */
155 public PendingIntent contentIntent;
156
157 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500158 * The intent to execute when the notification is explicitly dismissed by the user, either with
159 * the "Clear All" button or by swiping it away individually.
160 *
161 * This probably shouldn't be launching an activity since several of those will be sent
162 * at the same time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 */
164 public PendingIntent deleteIntent;
165
166 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700167 * An intent to launch instead of posting the notification to the status bar.
Joe Onoratocb109a02011-01-18 17:57:41 -0800168 *
169 * @see Notification.Builder#setFullScreenIntent
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400170 */
171 public PendingIntent fullScreenIntent;
172
173 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 * Text to scroll across the screen when this item is added to
Joe Onoratoef1e7762010-09-17 18:38:38 -0400175 * the status bar on large and smaller devices.
176 *
Joe Onorato46439ce2010-11-19 13:56:21 -0800177 * @see #tickerView
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 */
179 public CharSequence tickerText;
180
181 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800182 * The view to show as the ticker in the status bar when the notification
183 * is posted.
Joe Onoratoef1e7762010-09-17 18:38:38 -0400184 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800185 public RemoteViews tickerView;
Joe Onoratoef1e7762010-09-17 18:38:38 -0400186
187 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400188 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 */
190 public RemoteViews contentView;
191
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400192 /**
193 * The view that will represent this notification in the pop-up "intruder alert" dialog.
194 * @hide
195 */
196 public RemoteViews intruderView;
197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 /**
Daniel Sandler4dfbe832012-04-11 14:51:46 -0400199 * A large-format version of {@link #contentView}, giving the Notification an
Daniel Sandlerf3b73432012-03-27 15:01:25 -0400200 * opportunity to show more detail. The system UI may choose to show this
201 * instead of the normal content view at its discretion.
Daniel Sandlerf3b73432012-03-27 15:01:25 -0400202 */
203 public RemoteViews bigContentView;
204
205 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800206 * The bitmap that may escape the bounds of the panel and bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800208 public Bitmap largeIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209
210 /**
211 * The sound to play.
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500212 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 * <p>
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500214 * To play the default notification sound, see {@link #defaults}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 * </p>
216 */
217 public Uri sound;
218
219 /**
220 * Use this constant as the value for audioStreamType to request that
221 * the default stream type for notifications be used. Currently the
222 * default stream type is STREAM_RING.
223 */
224 public static final int STREAM_DEFAULT = -1;
225
226 /**
227 * The audio stream type to use when playing the sound.
228 * Should be one of the STREAM_ constants from
229 * {@link android.media.AudioManager}.
230 */
231 public int audioStreamType = STREAM_DEFAULT;
232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500234 * The pattern with which to vibrate.
235 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 * <p>
237 * To vibrate the default pattern, see {@link #defaults}.
238 * </p>
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500239 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 * @see android.os.Vibrator#vibrate(long[],int)
241 */
242 public long[] vibrate;
243
244 /**
245 * The color of the led. The hardware will do its best approximation.
246 *
247 * @see #FLAG_SHOW_LIGHTS
248 * @see #flags
249 */
250 public int ledARGB;
251
252 /**
253 * The number of milliseconds for the LED to be on while it's flashing.
254 * The hardware will do its best approximation.
255 *
256 * @see #FLAG_SHOW_LIGHTS
257 * @see #flags
258 */
259 public int ledOnMS;
260
261 /**
262 * The number of milliseconds for the LED to be off while it's flashing.
263 * The hardware will do its best approximation.
264 *
265 * @see #FLAG_SHOW_LIGHTS
266 * @see #flags
267 */
268 public int ledOffMS;
269
270 /**
271 * Specifies which values should be taken from the defaults.
272 * <p>
273 * To set, OR the desired from {@link #DEFAULT_SOUND},
274 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
275 * values, use {@link #DEFAULT_ALL}.
276 * </p>
277 */
278 public int defaults;
279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 /**
281 * Bit to be bitwise-ored into the {@link #flags} field that should be
282 * set if you want the LED on for this notification.
283 * <ul>
284 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
285 * or 0 for both ledOnMS and ledOffMS.</li>
286 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
287 * <li>To flash the LED, pass the number of milliseconds that it should
288 * be on and off to ledOnMS and ledOffMS.</li>
289 * </ul>
290 * <p>
291 * Since hardware varies, you are not guaranteed that any of the values
292 * you pass are honored exactly. Use the system defaults (TODO) if possible
293 * because they will be set to values that work on any given hardware.
294 * <p>
295 * The alpha channel must be set for forward compatibility.
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500296 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 */
298 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
299
300 /**
301 * Bit to be bitwise-ored into the {@link #flags} field that should be
302 * set if this notification is in reference to something that is ongoing,
303 * like a phone call. It should not be set if this notification is in
304 * reference to something that happened at a particular point in time,
305 * like a missed phone call.
306 */
307 public static final int FLAG_ONGOING_EVENT = 0x00000002;
308
309 /**
310 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700311 * the audio will be repeated until the notification is
312 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 */
314 public static final int FLAG_INSISTENT = 0x00000004;
315
316 /**
317 * Bit to be bitwise-ored into the {@link #flags} field that should be
318 * set if you want the sound and/or vibration play each time the
319 * notification is sent, even if it has not been canceled before that.
320 */
321 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
322
323 /**
324 * Bit to be bitwise-ored into the {@link #flags} field that should be
325 * set if the notification should be canceled when it is clicked by the
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500326 * user. On tablets, the
327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 */
329 public static final int FLAG_AUTO_CANCEL = 0x00000010;
330
331 /**
332 * Bit to be bitwise-ored into the {@link #flags} field that should be
333 * set if the notification should not be canceled when the user clicks
334 * the Clear all button.
335 */
336 public static final int FLAG_NO_CLEAR = 0x00000020;
337
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700338 /**
339 * Bit to be bitwise-ored into the {@link #flags} field that should be
340 * set if this notification represents a currently running service. This
341 * will normally be set for you by {@link Service#startForeground}.
342 */
343 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
344
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400345 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500346 * Obsolete flag indicating high-priority notifications; use the priority field instead.
347 *
348 * @deprecated Use {@link #priority} with a positive value.
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400349 */
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500350 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 public int flags;
353
354 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500355 * Default notification {@link #priority}. If your application does not prioritize its own
356 * notifications, use this value for all notifications.
357 */
358 public static final int PRIORITY_DEFAULT = 0;
359
360 /**
361 * Lower {@link #priority}, for items that are less important. The UI may choose to show these
362 * items smaller, or at a different position in the list, compared with your app's
363 * {@link #PRIORITY_DEFAULT} items.
364 */
365 public static final int PRIORITY_LOW = -1;
366
367 /**
368 * Lowest {@link #priority}; these items might not be shown to the user except under special
369 * circumstances, such as detailed notification logs.
370 */
371 public static final int PRIORITY_MIN = -2;
372
373 /**
374 * Higher {@link #priority}, for more important notifications or alerts. The UI may choose to
375 * show these items larger, or at a different position in notification lists, compared with
376 * your app's {@link #PRIORITY_DEFAULT} items.
377 */
378 public static final int PRIORITY_HIGH = 1;
379
380 /**
381 * Highest {@link #priority}, for your application's most important items that require the
382 * user's prompt attention or input.
383 */
384 public static final int PRIORITY_MAX = 2;
385
386 /**
387 * Relative priority for this notification.
388 *
389 * Priority is an indication of how much of the user's valuable attention should be consumed by
390 * this notification. Low-priority notifications may be hidden from the user in certain
391 * situations, while the user might be interrupted for a higher-priority notification. The
392 * system will make a determination about how to interpret notification priority as described in
393 * MUMBLE MUMBLE.
394 */
395 public int priority;
396
397 /**
398 * Notification type: incoming call (voice or video) or similar synchronous communication request.
399 */
400 public static final String KIND_CALL = "android.call";
401
402 /**
403 * Notification type: incoming direct message (SMS, instant message, etc.).
404 */
405 public static final String KIND_MESSAGE = "android.message";
406
407 /**
408 * Notification type: asynchronous bulk message (email).
409 */
410 public static final String KIND_EMAIL = "android.email";
411
412 /**
413 * Notification type: calendar event.
414 */
415 public static final String KIND_EVENT = "android.event";
416
417 /**
418 * Notification type: promotion or advertisement.
419 */
420 public static final String KIND_PROMO = "android.promo";
421
422 /**
423 * If this notification matches of one or more special types (see the <code>KIND_*</code>
424 * constants), add them here, best match first.
425 */
426 public String[] kind;
427
428 /**
429 * Extra key for people values (type TBD).
430 *
431 * @hide
432 */
433 public static final String EXTRA_PEOPLE = "android.people";
434
435 private Bundle extras;
436
437 /**
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400438 * Structure to encapsulate an "action", including title and icon, that can be attached to a Notification.
439 * @hide
440 */
441 private static class Action implements Parcelable {
442 public int icon;
443 public CharSequence title;
444 public PendingIntent actionIntent;
445 @SuppressWarnings("unused")
446 public Action() { }
447 private Action(Parcel in) {
448 icon = in.readInt();
449 title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
450 if (in.readInt() == 1) {
451 actionIntent = PendingIntent.CREATOR.createFromParcel(in);
452 }
453 }
454 public Action(int icon_, CharSequence title_, PendingIntent intent_) {
455 this.icon = icon_;
456 this.title = title_;
457 this.actionIntent = intent_;
458 }
459 @Override
460 public Action clone() {
461 return new Action(
462 this.icon,
463 this.title.toString(),
464 this.actionIntent // safe to alias
465 );
466 }
467 @Override
468 public int describeContents() {
469 return 0;
470 }
471 @Override
472 public void writeToParcel(Parcel out, int flags) {
473 out.writeInt(icon);
474 TextUtils.writeToParcel(title, out, flags);
475 if (actionIntent != null) {
476 out.writeInt(1);
477 actionIntent.writeToParcel(out, flags);
478 } else {
479 out.writeInt(0);
480 }
481 }
482 public static final Parcelable.Creator<Action> CREATOR
483 = new Parcelable.Creator<Action>() {
484 public Action createFromParcel(Parcel in) {
485 return new Action(in);
486 }
487 public Action[] newArray(int size) {
488 return new Action[size];
489 }
490 };
491 }
492
493 private Action[] actions;
494
495 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500496 * Constructs a Notification object with default values.
Joe Onorato46439ce2010-11-19 13:56:21 -0800497 * You might want to consider using {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 */
499 public Notification()
500 {
501 this.when = System.currentTimeMillis();
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500502 this.priority = PRIORITY_DEFAULT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 }
504
505 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 * @hide
507 */
508 public Notification(Context context, int icon, CharSequence tickerText, long when,
509 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
510 {
511 this.when = when;
512 this.icon = icon;
513 this.tickerText = tickerText;
514 setLatestEventInfo(context, contentTitle, contentText,
515 PendingIntent.getActivity(context, 0, contentIntent, 0));
516 }
517
518 /**
519 * Constructs a Notification object with the information needed to
520 * have a status bar icon without the standard expanded view.
521 *
522 * @param icon The resource id of the icon to put in the status bar.
523 * @param tickerText The text that flows by in the status bar when the notification first
524 * activates.
525 * @param when The time to show in the time field. In the System.currentTimeMillis
526 * timebase.
Joe Onorato46439ce2010-11-19 13:56:21 -0800527 *
528 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800530 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 public Notification(int icon, CharSequence tickerText, long when)
532 {
533 this.icon = icon;
534 this.tickerText = tickerText;
535 this.when = when;
536 }
537
538 /**
539 * Unflatten the notification from a parcel.
540 */
541 public Notification(Parcel parcel)
542 {
543 int version = parcel.readInt();
544
545 when = parcel.readLong();
546 icon = parcel.readInt();
547 number = parcel.readInt();
548 if (parcel.readInt() != 0) {
549 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
550 }
551 if (parcel.readInt() != 0) {
552 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
553 }
554 if (parcel.readInt() != 0) {
555 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
556 }
557 if (parcel.readInt() != 0) {
Joe Onorato46439ce2010-11-19 13:56:21 -0800558 tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400559 }
560 if (parcel.readInt() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
562 }
Joe Onorato561d3852010-11-20 18:09:34 -0800563 if (parcel.readInt() != 0) {
564 largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 defaults = parcel.readInt();
567 flags = parcel.readInt();
568 if (parcel.readInt() != 0) {
569 sound = Uri.CREATOR.createFromParcel(parcel);
570 }
571
572 audioStreamType = parcel.readInt();
573 vibrate = parcel.createLongArray();
574 ledARGB = parcel.readInt();
575 ledOnMS = parcel.readInt();
576 ledOffMS = parcel.readInt();
577 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400578
579 if (parcel.readInt() != 0) {
580 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
581 }
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500582
583 priority = parcel.readInt();
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400584
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500585 kind = parcel.createStringArray(); // may set kind to null
586
587 if (parcel.readInt() != 0) {
588 extras = parcel.readBundle();
589 }
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400590
591 actions = parcel.createTypedArray(Action.CREATOR);
592 if (parcel.readInt() != 0) {
593 intruderView = RemoteViews.CREATOR.createFromParcel(parcel);
594 }
Daniel Sandlerf3b73432012-03-27 15:01:25 -0400595 if (parcel.readInt() != 0) {
596 bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 }
599
Andy Stadler110988c2010-12-03 14:29:16 -0800600 @Override
Joe Onorato18e69df2010-05-17 22:26:12 -0700601 public Notification clone() {
602 Notification that = new Notification();
603
604 that.when = this.when;
605 that.icon = this.icon;
606 that.number = this.number;
607
608 // PendingIntents are global, so there's no reason (or way) to clone them.
609 that.contentIntent = this.contentIntent;
610 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400611 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700612
613 if (this.tickerText != null) {
614 that.tickerText = this.tickerText.toString();
615 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800616 if (this.tickerView != null) {
617 that.tickerView = this.tickerView.clone();
Joe Onoratoef1e7762010-09-17 18:38:38 -0400618 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700619 if (this.contentView != null) {
620 that.contentView = this.contentView.clone();
621 }
Joe Onorato561d3852010-11-20 18:09:34 -0800622 if (this.largeIcon != null) {
623 that.largeIcon = Bitmap.createBitmap(this.largeIcon);
624 }
Jozef BABJAKa8b91832011-02-22 08:05:08 +0100625 that.iconLevel = this.iconLevel;
Joe Onorato18e69df2010-05-17 22:26:12 -0700626 that.sound = this.sound; // android.net.Uri is immutable
627 that.audioStreamType = this.audioStreamType;
628
629 final long[] vibrate = this.vibrate;
630 if (vibrate != null) {
631 final int N = vibrate.length;
632 final long[] vib = that.vibrate = new long[N];
633 System.arraycopy(vibrate, 0, vib, 0, N);
634 }
635
636 that.ledARGB = this.ledARGB;
637 that.ledOnMS = this.ledOnMS;
638 that.ledOffMS = this.ledOffMS;
639 that.defaults = this.defaults;
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500640
Joe Onorato18e69df2010-05-17 22:26:12 -0700641 that.flags = this.flags;
642
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500643 that.priority = this.priority;
644
645 final String[] thiskind = this.kind;
646 if (thiskind != null) {
647 final int N = thiskind.length;
648 final String[] thatkind = that.kind = new String[N];
649 System.arraycopy(thiskind, 0, thatkind, 0, N);
650 }
651
652 if (this.extras != null) {
653 that.extras = new Bundle(this.extras);
654
655 }
656
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400657 that.actions = new Action[this.actions.length];
658 for(int i=0; i<this.actions.length; i++) {
659 that.actions[i] = this.actions[i].clone();
660 }
661 if (this.intruderView != null) {
662 that.intruderView = this.intruderView.clone();
663 }
Daniel Sandlerf3b73432012-03-27 15:01:25 -0400664 if (this.bigContentView != null) {
665 that.bigContentView = this.bigContentView.clone();
666 }
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400667
Joe Onorato18e69df2010-05-17 22:26:12 -0700668 return that;
669 }
670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 public int describeContents() {
672 return 0;
673 }
674
675 /**
676 * Flatten this notification from a parcel.
677 */
678 public void writeToParcel(Parcel parcel, int flags)
679 {
680 parcel.writeInt(1);
681
682 parcel.writeLong(when);
683 parcel.writeInt(icon);
684 parcel.writeInt(number);
685 if (contentIntent != null) {
686 parcel.writeInt(1);
687 contentIntent.writeToParcel(parcel, 0);
688 } else {
689 parcel.writeInt(0);
690 }
691 if (deleteIntent != null) {
692 parcel.writeInt(1);
693 deleteIntent.writeToParcel(parcel, 0);
694 } else {
695 parcel.writeInt(0);
696 }
697 if (tickerText != null) {
698 parcel.writeInt(1);
699 TextUtils.writeToParcel(tickerText, parcel, flags);
700 } else {
701 parcel.writeInt(0);
702 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800703 if (tickerView != null) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400704 parcel.writeInt(1);
Joe Onorato46439ce2010-11-19 13:56:21 -0800705 tickerView.writeToParcel(parcel, 0);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400706 } else {
707 parcel.writeInt(0);
708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800709 if (contentView != null) {
710 parcel.writeInt(1);
711 contentView.writeToParcel(parcel, 0);
712 } else {
713 parcel.writeInt(0);
714 }
Joe Onorato561d3852010-11-20 18:09:34 -0800715 if (largeIcon != null) {
716 parcel.writeInt(1);
717 largeIcon.writeToParcel(parcel, 0);
718 } else {
719 parcel.writeInt(0);
720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721
722 parcel.writeInt(defaults);
723 parcel.writeInt(this.flags);
724
725 if (sound != null) {
726 parcel.writeInt(1);
727 sound.writeToParcel(parcel, 0);
728 } else {
729 parcel.writeInt(0);
730 }
731 parcel.writeInt(audioStreamType);
732 parcel.writeLongArray(vibrate);
733 parcel.writeInt(ledARGB);
734 parcel.writeInt(ledOnMS);
735 parcel.writeInt(ledOffMS);
736 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400737
738 if (fullScreenIntent != null) {
739 parcel.writeInt(1);
740 fullScreenIntent.writeToParcel(parcel, 0);
741 } else {
742 parcel.writeInt(0);
743 }
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500744
745 parcel.writeInt(priority);
746
747 parcel.writeStringArray(kind); // ok for null
748
749 if (extras != null) {
750 parcel.writeInt(1);
751 extras.writeToParcel(parcel, 0);
752 } else {
753 parcel.writeInt(0);
754 }
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400755
756 parcel.writeTypedArray(actions, 0);
757
758 if (intruderView != null) {
759 parcel.writeInt(1);
760 intruderView.writeToParcel(parcel, 0);
761 } else {
762 parcel.writeInt(0);
763 }
Daniel Sandlerf3b73432012-03-27 15:01:25 -0400764
765 if (bigContentView != null) {
766 parcel.writeInt(1);
767 bigContentView.writeToParcel(parcel, 0);
768 } else {
769 parcel.writeInt(0);
770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 }
772
773 /**
774 * Parcelable.Creator that instantiates Notification objects
775 */
776 public static final Parcelable.Creator<Notification> CREATOR
777 = new Parcelable.Creator<Notification>()
778 {
779 public Notification createFromParcel(Parcel parcel)
780 {
781 return new Notification(parcel);
782 }
783
784 public Notification[] newArray(int size)
785 {
786 return new Notification[size];
787 }
788 };
789
790 /**
791 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
792 * layout.
793 *
794 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
795 * in the view.</p>
796 * @param context The context for your application / activity.
797 * @param contentTitle The title that goes in the expanded entry.
798 * @param contentText The text that goes in the expanded entry.
799 * @param contentIntent The intent to launch when the user clicks the expanded notification.
800 * If this is an activity, it must include the
801 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800802 * that you take care of task management as described in the
803 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
804 * Stack</a> document.
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500805 *
Joe Onorato46439ce2010-11-19 13:56:21 -0800806 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800808 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 public void setLatestEventInfo(Context context,
810 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
Daniel Sandlercde8aae2012-04-04 23:40:22 -0400811 // TODO: rewrite this to use Builder
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 RemoteViews contentView = new RemoteViews(context.getPackageName(),
Daniel Sandler96fd7c12012-03-30 16:37:36 -0400813 R.layout.notification_template_base);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 if (this.icon != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800815 contentView.setImageViewResource(R.id.icon, this.icon);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 }
817 if (contentTitle != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800818 contentView.setTextViewText(R.id.title, contentTitle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 }
820 if (contentText != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800821 contentView.setTextViewText(R.id.text, contentText);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823 if (this.when != 0) {
Daniel Sandlercde8aae2012-04-04 23:40:22 -0400824 contentView.setViewVisibility(R.id.time, View.VISIBLE);
Joe Onorato561d3852010-11-20 18:09:34 -0800825 contentView.setLong(R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 }
827
828 this.contentView = contentView;
829 this.contentIntent = contentIntent;
830 }
831
832 @Override
833 public String toString() {
834 StringBuilder sb = new StringBuilder();
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500835 sb.append("Notification(pri=");
836 sb.append(priority);
837 sb.append(" contentView=");
Joe Onoratoc9596d62011-01-12 17:03:11 -0800838 if (contentView != null) {
839 sb.append(contentView.getPackage());
840 sb.append("/0x");
841 sb.append(Integer.toHexString(contentView.getLayoutId()));
842 } else {
843 sb.append("null");
844 }
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500845 // TODO(dsandler): defaults take precedence over local values, so reorder the branches below
Joe Onoratoc9596d62011-01-12 17:03:11 -0800846 sb.append(" vibrate=");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 if (this.vibrate != null) {
848 int N = this.vibrate.length-1;
849 sb.append("[");
850 for (int i=0; i<N; i++) {
851 sb.append(this.vibrate[i]);
852 sb.append(',');
853 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200854 if (N != -1) {
855 sb.append(this.vibrate[N]);
856 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 sb.append("]");
858 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
859 sb.append("default");
860 } else {
861 sb.append("null");
862 }
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500863 sb.append(" sound=");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 if (this.sound != null) {
865 sb.append(this.sound.toString());
866 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
867 sb.append("default");
868 } else {
869 sb.append("null");
870 }
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500871 sb.append(" defaults=0x");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 sb.append(Integer.toHexString(this.defaults));
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500873 sb.append(" flags=0x");
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400874 sb.append(Integer.toHexString(this.flags));
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500875 sb.append(" kind=[");
876 if (this.kind == null) {
877 sb.append("null");
878 } else {
879 for (int i=0; i<this.kind.length; i++) {
880 if (i>0) sb.append(",");
881 sb.append(this.kind[i]);
882 }
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400883 }
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400884 sb.append("]");
885 if (actions != null) {
886 sb.append(" ");
887 sb.append(actions.length);
888 sb.append(" action");
889 if (actions.length > 1) sb.append("s");
890 }
891 sb.append(")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 return sb.toString();
893 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800894
Joe Onoratocb109a02011-01-18 17:57:41 -0800895 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500896 * Builder class for {@link Notification} objects.
897 *
898 * Provides a convenient way to set the various fields of a {@link Notification} and generate
899 * content views using the platform's notification layout template.
900 *
901 * Example:
902 *
903 * <pre class="prettyprint">
904 * Notification noti = new Notification.Builder()
905 * .setContentTitle(&quot;New mail from &quot; + sender.toString())
906 * .setContentText(subject)
907 * .setSmallIcon(R.drawable.new_mail)
908 * .setLargeIcon(aBitmap)
909 * .getNotification();
910 * </pre>
Joe Onoratocb109a02011-01-18 17:57:41 -0800911 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800912 public static class Builder {
913 private Context mContext;
914
915 private long mWhen;
916 private int mSmallIcon;
917 private int mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800918 private int mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800919 private CharSequence mContentTitle;
920 private CharSequence mContentText;
921 private CharSequence mContentInfo;
Daniel Sandlerf3b73432012-03-27 15:01:25 -0400922 private CharSequence mSubText;
Joe Onorato46439ce2010-11-19 13:56:21 -0800923 private PendingIntent mContentIntent;
924 private RemoteViews mContentView;
925 private PendingIntent mDeleteIntent;
926 private PendingIntent mFullScreenIntent;
927 private CharSequence mTickerText;
928 private RemoteViews mTickerView;
929 private Bitmap mLargeIcon;
930 private Uri mSound;
931 private int mAudioStreamType;
932 private long[] mVibrate;
933 private int mLedArgb;
934 private int mLedOnMs;
935 private int mLedOffMs;
936 private int mDefaults;
937 private int mFlags;
Jeff Sharkey1c400132011-08-05 14:50:13 -0700938 private int mProgressMax;
939 private int mProgress;
940 private boolean mProgressIndeterminate;
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500941 private ArrayList<String> mKindList = new ArrayList<String>(1);
942 private Bundle mExtras;
943 private int mPriority;
Daniel Sandlera0a938c2012-03-15 08:42:37 -0400944 private ArrayList<Action> mActions = new ArrayList<Action>(3);
Daniel Sandlerb2a1c232012-03-24 10:37:28 -0500945 private boolean mCanHasIntruder;
946 private boolean mIntruderActionsShowText;
Daniel Sandlera2985ed2012-04-03 16:42:00 -0400947 private boolean mUseChronometer;
Joe Onorato46439ce2010-11-19 13:56:21 -0800948
Joe Onoratocb109a02011-01-18 17:57:41 -0800949 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500950 * Constructs a new Builder with the defaults:
Joe Onoratocb109a02011-01-18 17:57:41 -0800951 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500952
953 * <table>
954 * <tr><th align=right>priority</th>
955 * <td>{@link #PRIORITY_DEFAULT}</td></tr>
956 * <tr><th align=right>when</th>
957 * <td>now ({@link System#currentTimeMillis()})</td></tr>
958 * <tr><th align=right>audio stream</th>
959 * <td>{@link #STREAM_DEFAULT}</td></tr>
960 * </table>
Joe Onoratocb109a02011-01-18 17:57:41 -0800961 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500962
963 * @param context
964 * A {@link Context} that will be used by the Builder to construct the
965 * RemoteViews. The Context will not be held past the lifetime of this Builder
966 * object.
Joe Onoratocb109a02011-01-18 17:57:41 -0800967 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800968 public Builder(Context context) {
969 mContext = context;
Andy Stadler110988c2010-12-03 14:29:16 -0800970
971 // Set defaults to match the defaults of a Notification
Joe Onorato46439ce2010-11-19 13:56:21 -0800972 mWhen = System.currentTimeMillis();
Andy Stadler110988c2010-12-03 14:29:16 -0800973 mAudioStreamType = STREAM_DEFAULT;
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500974 mPriority = PRIORITY_DEFAULT;
Joe Onorato46439ce2010-11-19 13:56:21 -0800975 }
976
Joe Onoratocb109a02011-01-18 17:57:41 -0800977 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500978 * Add a timestamp pertaining to the notification (usually the time the event occurred).
979 *
980
981 * @see Notification#when
Joe Onoratocb109a02011-01-18 17:57:41 -0800982 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800983 public Builder setWhen(long when) {
984 mWhen = when;
985 return this;
986 }
987
Joe Onoratocb109a02011-01-18 17:57:41 -0800988 /**
Daniel Sandlera2985ed2012-04-03 16:42:00 -0400989 * Show the {@link Notification#when} field as a countdown (or count-up) timer instead of a timestamp.
990 *
991 * @see Notification#when
992 */
993 public Builder setUsesChronometer(boolean b) {
994 mUseChronometer = b;
995 return this;
996 }
997
998 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500999 * Set the small icon resource, which will be used to represent the notification in the
1000 * status bar.
Joe Onoratocb109a02011-01-18 17:57:41 -08001001 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001002
1003 * The platform template for the expanded view will draw this icon in the left, unless a
1004 * {@link #setLargeIcon(Bitmap) large icon} has also been specified, in which case the small
1005 * icon will be moved to the right-hand side.
1006 *
1007
1008 * @param icon
1009 * A resource ID in the application's package of the drawable to use.
1010 * @see Notification#icon
Joe Onoratocb109a02011-01-18 17:57:41 -08001011 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001012 public Builder setSmallIcon(int icon) {
1013 mSmallIcon = icon;
1014 return this;
1015 }
1016
Joe Onoratocb109a02011-01-18 17:57:41 -08001017 /**
1018 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
1019 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
1020 * LevelListDrawable}.
1021 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001022 * @param icon A resource ID in the application's package of the drawable to use.
Joe Onoratocb109a02011-01-18 17:57:41 -08001023 * @param level The level to use for the icon.
1024 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001025 * @see Notification#icon
1026 * @see Notification#iconLevel
Joe Onoratocb109a02011-01-18 17:57:41 -08001027 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001028 public Builder setSmallIcon(int icon, int level) {
1029 mSmallIcon = icon;
1030 mSmallIconLevel = level;
1031 return this;
1032 }
1033
Joe Onoratocb109a02011-01-18 17:57:41 -08001034 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001035 * Set the first line of text in the platform notification template.
Joe Onoratocb109a02011-01-18 17:57:41 -08001036 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001037 public Builder setContentTitle(CharSequence title) {
1038 mContentTitle = title;
1039 return this;
1040 }
1041
Joe Onoratocb109a02011-01-18 17:57:41 -08001042 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001043 * Set the second line of text in the platform notification template.
Joe Onoratocb109a02011-01-18 17:57:41 -08001044 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001045 public Builder setContentText(CharSequence text) {
1046 mContentText = text;
1047 return this;
1048 }
1049
Joe Onoratocb109a02011-01-18 17:57:41 -08001050 /**
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001051 * Set the third line of text in the platform notification template.
1052 * Don't use if you're also using {@link #setProgress(int, int, boolean)}; they occupy the same location in the standard template.
1053 */
1054 public Builder setSubText(CharSequence text) {
1055 mSubText = text;
1056 return this;
1057 }
1058
1059 /**
Joe Onoratocb109a02011-01-18 17:57:41 -08001060 * Set the large number at the right-hand side of the notification. This is
1061 * equivalent to setContentInfo, although it might show the number in a different
1062 * font size for readability.
1063 */
Joe Onorato8595a3d2010-11-19 18:12:07 -08001064 public Builder setNumber(int number) {
1065 mNumber = number;
1066 return this;
1067 }
1068
Joe Onoratocb109a02011-01-18 17:57:41 -08001069 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001070 * A small piece of additional information pertaining to this notification.
1071 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001072 * The platform template will draw this on the last line of the notification, at the far
1073 * right (to the right of a smallIcon if it has been placed there).
Joe Onoratocb109a02011-01-18 17:57:41 -08001074 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001075 public Builder setContentInfo(CharSequence info) {
1076 mContentInfo = info;
1077 return this;
1078 }
1079
Joe Onoratocb109a02011-01-18 17:57:41 -08001080 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001081 * Set the progress this notification represents.
1082 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001083 * The platform template will represent this using a {@link ProgressBar}.
Jeff Sharkey1c400132011-08-05 14:50:13 -07001084 */
1085 public Builder setProgress(int max, int progress, boolean indeterminate) {
1086 mProgressMax = max;
1087 mProgress = progress;
1088 mProgressIndeterminate = indeterminate;
1089 return this;
1090 }
1091
1092 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001093 * Supply a custom RemoteViews to use instead of the platform template.
1094 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001095 * @see Notification#contentView
Joe Onoratocb109a02011-01-18 17:57:41 -08001096 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001097 public Builder setContent(RemoteViews views) {
1098 mContentView = views;
1099 return this;
1100 }
1101
Joe Onoratocb109a02011-01-18 17:57:41 -08001102 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001103 * Supply a {@link PendingIntent} to be sent when the notification is clicked.
1104 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001105 * As of {@link android.os.Build.VERSION_CODES#HONEYCOMB}, if this field is unset and you
1106 * have specified a custom RemoteViews with {@link #setContent(RemoteViews)}, you can use
1107 * {@link RemoteViews#setOnClickPendingIntent RemoteViews.setOnClickPendingIntent(int,PendingIntent)}
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001108 * to assign PendingIntents to individual views in that custom layout (i.e., to create
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001109 * clickable buttons inside the notification view).
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001110 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001111 * @see Notification#contentIntent Notification.contentIntent
Joe Onoratocb109a02011-01-18 17:57:41 -08001112 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001113 public Builder setContentIntent(PendingIntent intent) {
1114 mContentIntent = intent;
1115 return this;
1116 }
1117
Joe Onoratocb109a02011-01-18 17:57:41 -08001118 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001119 * Supply a {@link PendingIntent} to send when the notification is cleared explicitly by the user.
1120 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001121 * @see Notification#deleteIntent
Joe Onoratocb109a02011-01-18 17:57:41 -08001122 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001123 public Builder setDeleteIntent(PendingIntent intent) {
1124 mDeleteIntent = intent;
1125 return this;
1126 }
1127
Joe Onoratocb109a02011-01-18 17:57:41 -08001128 /**
1129 * An intent to launch instead of posting the notification to the status bar.
1130 * Only for use with extremely high-priority notifications demanding the user's
1131 * <strong>immediate</strong> attention, such as an incoming phone call or
1132 * alarm clock that the user has explicitly set to a particular time.
1133 * If this facility is used for something else, please give the user an option
1134 * to turn it off and use a normal notification, as this can be extremely
1135 * disruptive.
1136 *
1137 * @param intent The pending intent to launch.
1138 * @param highPriority Passing true will cause this notification to be sent
1139 * even if other notifications are suppressed.
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001140 *
1141 * @see Notification#fullScreenIntent
Joe Onoratocb109a02011-01-18 17:57:41 -08001142 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001143 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
1144 mFullScreenIntent = intent;
1145 setFlag(FLAG_HIGH_PRIORITY, highPriority);
1146 return this;
1147 }
1148
Joe Onoratocb109a02011-01-18 17:57:41 -08001149 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001150 * Set the "ticker" text which is displayed in the status bar when the notification first
Joe Onoratocb109a02011-01-18 17:57:41 -08001151 * arrives.
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001152 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001153 * @see Notification#tickerText
Joe Onoratocb109a02011-01-18 17:57:41 -08001154 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001155 public Builder setTicker(CharSequence tickerText) {
1156 mTickerText = tickerText;
1157 return this;
1158 }
1159
Joe Onoratocb109a02011-01-18 17:57:41 -08001160 /**
1161 * Set the text that is displayed in the status bar when the notification first
1162 * arrives, and also a RemoteViews object that may be displayed instead on some
1163 * devices.
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001164 *
1165 * @see Notification#tickerText
1166 * @see Notification#tickerView
Joe Onoratocb109a02011-01-18 17:57:41 -08001167 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001168 public Builder setTicker(CharSequence tickerText, RemoteViews views) {
1169 mTickerText = tickerText;
1170 mTickerView = views;
1171 return this;
1172 }
1173
Joe Onoratocb109a02011-01-18 17:57:41 -08001174 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001175 * Add a large icon to the notification (and the ticker on some devices).
1176 *
1177 * In the platform template, this image will be shown on the left of the notification view
1178 * in place of the {@link #setSmallIcon(int) small icon} (which will move to the right side).
1179 *
1180 * @see Notification#largeIcon
Joe Onoratocb109a02011-01-18 17:57:41 -08001181 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001182 public Builder setLargeIcon(Bitmap icon) {
1183 mLargeIcon = icon;
1184 return this;
1185 }
1186
Joe Onoratocb109a02011-01-18 17:57:41 -08001187 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001188 * Set the sound to play.
1189 *
1190 * It will be played on the {@link #STREAM_DEFAULT default stream} for notifications.
1191 *
1192 * @see Notification#sound
Joe Onoratocb109a02011-01-18 17:57:41 -08001193 */
Joe Onorato52f80cd2010-11-21 15:34:48 -08001194 public Builder setSound(Uri sound) {
1195 mSound = sound;
1196 mAudioStreamType = STREAM_DEFAULT;
1197 return this;
1198 }
1199
Joe Onoratocb109a02011-01-18 17:57:41 -08001200 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001201 * Set the sound to play, along with a specific stream on which to play it.
Joe Onoratocb109a02011-01-18 17:57:41 -08001202 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001203 * See {@link android.media.AudioManager} for the <code>STREAM_</code> constants.
1204 *
1205 * @see Notification#sound
Joe Onoratocb109a02011-01-18 17:57:41 -08001206 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001207 public Builder setSound(Uri sound, int streamType) {
1208 mSound = sound;
1209 mAudioStreamType = streamType;
1210 return this;
1211 }
1212
Joe Onoratocb109a02011-01-18 17:57:41 -08001213 /**
1214 * Set the vibration pattern to use.
1215 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001216
1217 * See {@link android.os.Vibrator#vibrate(long[], int)} for a discussion of the
1218 * <code>pattern</code> parameter.
1219 *
1220
1221 * @see Notification#vibrate
Joe Onoratocb109a02011-01-18 17:57:41 -08001222 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001223 public Builder setVibrate(long[] pattern) {
1224 mVibrate = pattern;
1225 return this;
1226 }
1227
Joe Onoratocb109a02011-01-18 17:57:41 -08001228 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001229 * Set the desired color for the indicator LED on the device, as well as the
1230 * blink duty cycle (specified in milliseconds).
1231 *
1232
1233 * Not all devices will honor all (or even any) of these values.
1234 *
1235
1236 * @see Notification#ledARGB
1237 * @see Notification#ledOnMS
1238 * @see Notification#ledOffMS
Joe Onoratocb109a02011-01-18 17:57:41 -08001239 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001240 public Builder setLights(int argb, int onMs, int offMs) {
1241 mLedArgb = argb;
1242 mLedOnMs = onMs;
1243 mLedOffMs = offMs;
Joe Onorato46439ce2010-11-19 13:56:21 -08001244 return this;
1245 }
1246
Joe Onoratocb109a02011-01-18 17:57:41 -08001247 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001248 * Set whether this is an "ongoing" notification.
Joe Onoratocb109a02011-01-18 17:57:41 -08001249 *
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001250
1251 * Ongoing notifications cannot be dismissed by the user, so your application or service
1252 * must take care of canceling them.
1253 *
1254
1255 * They are typically used to indicate a background task that the user is actively engaged
1256 * with (e.g., playing music) or is pending in some way and therefore occupying the device
1257 * (e.g., a file download, sync operation, active network connection).
1258 *
1259
1260 * @see Notification#FLAG_ONGOING_EVENT
1261 * @see Service#setForeground(boolean)
Joe Onoratocb109a02011-01-18 17:57:41 -08001262 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001263 public Builder setOngoing(boolean ongoing) {
1264 setFlag(FLAG_ONGOING_EVENT, ongoing);
1265 return this;
1266 }
1267
Joe Onoratocb109a02011-01-18 17:57:41 -08001268 /**
1269 * Set this flag if you would only like the sound, vibrate
1270 * and ticker to be played if the notification is not already showing.
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001271 *
1272 * @see Notification#FLAG_ONLY_ALERT_ONCE
Joe Onoratocb109a02011-01-18 17:57:41 -08001273 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001274 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
1275 setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
1276 return this;
1277 }
1278
Joe Onoratocb109a02011-01-18 17:57:41 -08001279 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001280 * Make this notification automatically dismissed when the user touches it. The
1281 * PendingIntent set with {@link #setDeleteIntent} will be sent when this happens.
1282 *
1283 * @see Notification#FLAG_AUTO_CANCEL
Joe Onoratocb109a02011-01-18 17:57:41 -08001284 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001285 public Builder setAutoCancel(boolean autoCancel) {
Joe Onorato281d83f2011-01-04 17:13:10 -08001286 setFlag(FLAG_AUTO_CANCEL, autoCancel);
Joe Onorato46439ce2010-11-19 13:56:21 -08001287 return this;
1288 }
1289
Joe Onoratocb109a02011-01-18 17:57:41 -08001290 /**
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001291 * Set which notification properties will be inherited from system defaults.
Joe Onoratocb109a02011-01-18 17:57:41 -08001292 * <p>
1293 * The value should be one or more of the following fields combined with
1294 * bitwise-or:
1295 * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
1296 * <p>
1297 * For all default values, use {@link #DEFAULT_ALL}.
1298 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001299 public Builder setDefaults(int defaults) {
1300 mDefaults = defaults;
1301 return this;
1302 }
1303
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001304 /**
1305 * Set the priority of this notification.
1306 *
1307 * @see Notification#priority
1308 */
1309 public Builder setPriority(int pri) {
1310 mPriority = pri;
1311 return this;
1312 }
1313
1314 /**
1315 * Add a kind (category) to this notification. Optional.
1316 *
1317 * @see Notification#kind
1318 */
1319 public Builder addKind(String k) {
1320 mKindList.add(k);
1321 return this;
1322 }
1323
1324 /**
1325 * Add metadata to this notification.
1326 *
1327 * A reference to the Bundle is held for the lifetime of this Builder, and the Bundle's
1328 * current contents are copied into the Notification each time {@link #getNotification()} is
1329 * called.
1330 *
1331 * @see Notification#extras
1332 * @hide
1333 */
1334 public Builder setExtras(Bundle bag) {
1335 mExtras = bag;
1336 return this;
1337 }
1338
Daniel Sandlera0a938c2012-03-15 08:42:37 -04001339 /**
1340 * Add an action to this notification. Actions are typically displayed by
1341 * the system as a button adjacent to the notification content.
1342 *
1343 * @param icon Resource ID of a drawable that represents the action.
1344 * @param title Text describing the action.
1345 * @param intent PendingIntent to be fired when the action is invoked.
1346 */
1347 public Builder addAction(int icon, CharSequence title, PendingIntent intent) {
1348 mActions.add(new Action(icon, title, intent));
1349 return this;
1350 }
1351
Daniel Sandlerb2a1c232012-03-24 10:37:28 -05001352 /**
1353 * Specify whether this notification should pop up as an
1354 * "intruder alert" (a small window that shares the screen with the
1355 * current activity). This sort of notification is (as the name implies)
1356 * very intrusive, so use it sparingly for notifications that require
1357 * the user's attention.
1358 *
1359 * Notes:
1360 * <ul>
1361 * <li>Intruder alerts only show when the screen is on.</li>
1362 * <li>Intruder alerts take precedence over fullScreenIntents.</li>
1363 * </ul>
1364 *
1365 * @param intrude Whether to pop up an intruder alert (default false).
1366 */
1367 public Builder setUsesIntruderAlert(boolean intrude) {
1368 mCanHasIntruder = intrude;
1369 return this;
1370 }
1371
1372 /**
1373 * Control text on intruder alert action buttons. By default, action
1374 * buttons in intruders do not show textual labels.
1375 *
1376 * @param showActionText Whether to show text labels beneath action
1377 * icons (default false).
1378 */
1379 public Builder setIntruderActionsShowText(boolean showActionText) {
1380 mIntruderActionsShowText = showActionText;
1381 return this;
1382 }
1383
Joe Onorato46439ce2010-11-19 13:56:21 -08001384 private void setFlag(int mask, boolean value) {
1385 if (value) {
1386 mFlags |= mask;
1387 } else {
1388 mFlags &= ~mask;
1389 }
1390 }
1391
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001392 private RemoteViews applyStandardTemplate(int resId) {
Joe Onorato561d3852010-11-20 18:09:34 -08001393 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
Jeff Sharkey1c400132011-08-05 14:50:13 -07001394 boolean hasLine3 = false;
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001395 boolean hasLine2 = false;
1396 int smallIconImageViewId = R.id.icon;
1397 if (mLargeIcon != null) {
1398 contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
1399 smallIconImageViewId = R.id.right_icon;
1400 }
Joe Onorato561d3852010-11-20 18:09:34 -08001401 if (mSmallIcon != 0) {
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001402 contentView.setImageViewResource(smallIconImageViewId, mSmallIcon);
1403 contentView.setViewVisibility(smallIconImageViewId, View.VISIBLE);
Jeff Sharkey1c400132011-08-05 14:50:13 -07001404 } else {
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001405 contentView.setViewVisibility(smallIconImageViewId, View.GONE);
Joe Onorato561d3852010-11-20 18:09:34 -08001406 }
1407 if (mContentTitle != null) {
1408 contentView.setTextViewText(R.id.title, mContentTitle);
1409 }
1410 if (mContentText != null) {
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001411 contentView.setTextViewText(
1412 (mSubText != null) ? R.id.text2 : R.id.text,
1413 mContentText);
Jeff Sharkey1c400132011-08-05 14:50:13 -07001414 hasLine3 = true;
Joe Onorato561d3852010-11-20 18:09:34 -08001415 }
1416 if (mContentInfo != null) {
1417 contentView.setTextViewText(R.id.info, mContentInfo);
Jeff Sharkey1c400132011-08-05 14:50:13 -07001418 contentView.setViewVisibility(R.id.info, View.VISIBLE);
1419 hasLine3 = true;
Joe Onorato561d3852010-11-20 18:09:34 -08001420 } else if (mNumber > 0) {
Daniel Sandlerebce0112011-06-16 16:44:51 -04001421 final int tooBig = mContext.getResources().getInteger(
1422 R.integer.status_bar_notification_info_maxnum);
1423 if (mNumber > tooBig) {
1424 contentView.setTextViewText(R.id.info, mContext.getResources().getString(
1425 R.string.status_bar_notification_info_overflow));
Joe Onorato059a2f82011-01-04 10:27:01 -08001426 } else {
1427 NumberFormat f = NumberFormat.getIntegerInstance();
1428 contentView.setTextViewText(R.id.info, f.format(mNumber));
1429 }
Jeff Sharkey1c400132011-08-05 14:50:13 -07001430 contentView.setViewVisibility(R.id.info, View.VISIBLE);
1431 hasLine3 = true;
Joe Onorato561d3852010-11-20 18:09:34 -08001432 } else {
1433 contentView.setViewVisibility(R.id.info, View.GONE);
1434 }
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001435
1436 if (mSubText != null) {
1437 contentView.setTextViewText(R.id.text, mSubText);
1438 contentView.setViewVisibility(R.id.text2, View.VISIBLE);
Jeff Sharkey1c400132011-08-05 14:50:13 -07001439 } else {
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001440 contentView.setViewVisibility(R.id.text2, View.GONE);
1441 if (mProgressMax != 0 || mProgressIndeterminate) {
1442 contentView.setProgressBar(
1443 R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
1444 contentView.setViewVisibility(R.id.progress, View.VISIBLE);
1445 } else {
1446 contentView.setViewVisibility(R.id.progress, View.GONE);
1447 }
Jeff Sharkey1c400132011-08-05 14:50:13 -07001448 }
Joe Onorato561d3852010-11-20 18:09:34 -08001449 if (mWhen != 0) {
Daniel Sandlera2985ed2012-04-03 16:42:00 -04001450 if (mUseChronometer) {
1451 contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
1452 contentView.setLong(R.id.chronometer, "setBase",
1453 mWhen + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
1454 contentView.setBoolean(R.id.chronometer, "setStarted", true);
1455 } else {
1456 contentView.setViewVisibility(R.id.time, View.VISIBLE);
1457 contentView.setLong(R.id.time, "setTime", mWhen);
1458 }
Joe Onorato561d3852010-11-20 18:09:34 -08001459 }
Jeff Sharkey1c400132011-08-05 14:50:13 -07001460 contentView.setViewVisibility(R.id.line3, hasLine3 ? View.VISIBLE : View.GONE);
Joe Onorato561d3852010-11-20 18:09:34 -08001461 return contentView;
1462 }
1463
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001464 private RemoteViews applyStandardTemplateWithActions(int layoutId) {
1465 RemoteViews big = applyStandardTemplate(layoutId);
1466
1467 int N = mActions.size();
1468 if (N > 0) {
1469 Log.d("Notification", "has actions: " + mContentText);
1470 big.setViewVisibility(R.id.actions, View.VISIBLE);
1471 if (N>3) N=3;
1472 for (int i=0; i<N; i++) {
1473 final RemoteViews button = generateActionButton(mActions.get(i));
1474 Log.d("Notification", "adding action " + i + ": " + mActions.get(i).title);
1475 big.addView(R.id.actions, button);
1476 }
1477 }
1478 return big;
1479 }
1480
Joe Onorato46439ce2010-11-19 13:56:21 -08001481 private RemoteViews makeContentView() {
1482 if (mContentView != null) {
1483 return mContentView;
1484 } else {
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001485 return applyStandardTemplate(R.layout.notification_template_base); // no more special large_icon flavor
Joe Onorato46439ce2010-11-19 13:56:21 -08001486 }
1487 }
1488
1489 private RemoteViews makeTickerView() {
1490 if (mTickerView != null) {
1491 return mTickerView;
1492 } else {
Joe Onorato561d3852010-11-20 18:09:34 -08001493 if (mContentView == null) {
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001494 return applyStandardTemplate(mLargeIcon == null
Joe Onorato561d3852010-11-20 18:09:34 -08001495 ? R.layout.status_bar_latest_event_ticker
1496 : R.layout.status_bar_latest_event_ticker_large_icon);
1497 } else {
1498 return null;
1499 }
Joe Onorato46439ce2010-11-19 13:56:21 -08001500 }
1501 }
1502
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001503 private RemoteViews makeBigContentView() {
1504 if (mActions.size() == 0) return null;
1505
1506 return applyStandardTemplateWithActions(R.layout.notification_template_base);
1507 }
1508
Daniel Sandlerb2a1c232012-03-24 10:37:28 -05001509 private RemoteViews makeIntruderView(boolean showLabels) {
Daniel Sandlera0a938c2012-03-15 08:42:37 -04001510 RemoteViews intruderView = new RemoteViews(mContext.getPackageName(),
1511 R.layout.notification_intruder_content);
1512 if (mLargeIcon != null) {
1513 intruderView.setImageViewBitmap(R.id.icon, mLargeIcon);
1514 intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
1515 } else if (mSmallIcon != 0) {
1516 intruderView.setImageViewResource(R.id.icon, mSmallIcon);
1517 intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
1518 } else {
1519 intruderView.setViewVisibility(R.id.icon, View.GONE);
1520 }
1521 if (mContentTitle != null) {
1522 intruderView.setTextViewText(R.id.title, mContentTitle);
1523 }
1524 if (mContentText != null) {
1525 intruderView.setTextViewText(R.id.text, mContentText);
1526 }
1527 if (mActions.size() > 0) {
1528 intruderView.setViewVisibility(R.id.actions, View.VISIBLE);
1529 int N = mActions.size();
1530 if (N>3) N=3;
1531 final int[] BUTTONS = { R.id.action0, R.id.action1, R.id.action2 };
1532 for (int i=0; i<N; i++) {
1533 final Action action = mActions.get(i);
1534 final int buttonId = BUTTONS[i];
1535
1536 intruderView.setViewVisibility(buttonId, View.VISIBLE);
Daniel Sandlerb2a1c232012-03-24 10:37:28 -05001537 intruderView.setTextViewText(buttonId, showLabels ? action.title : null);
1538 intruderView.setTextViewCompoundDrawables(buttonId, 0, action.icon, 0, 0);
Daniel Sandlera0a938c2012-03-15 08:42:37 -04001539 intruderView.setContentDescription(buttonId, action.title);
1540 intruderView.setOnClickPendingIntent(buttonId, action.actionIntent);
1541 }
1542 } else {
1543 intruderView.setViewVisibility(R.id.actions, View.GONE);
1544 }
1545 return intruderView;
1546 }
1547
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001548 private RemoteViews generateActionButton(Action action) {
1549 RemoteViews button = new RemoteViews(mContext.getPackageName(), R.layout.notification_action);
1550 button.setTextViewCompoundDrawables(R.id.action0, action.icon, 0, 0, 0);
1551 button.setTextViewText(R.id.action0, action.title);
1552 button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
1553 button.setContentDescription(R.id.action0, action.title);
1554 return button;
1555 }
1556
Joe Onoratocb109a02011-01-18 17:57:41 -08001557 /**
1558 * Combine all of the options that have been set and return a new {@link Notification}
1559 * object.
1560 */
Joe Onorato46439ce2010-11-19 13:56:21 -08001561 public Notification getNotification() {
1562 Notification n = new Notification();
1563 n.when = mWhen;
1564 n.icon = mSmallIcon;
1565 n.iconLevel = mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -08001566 n.number = mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -08001567 n.contentView = makeContentView();
1568 n.contentIntent = mContentIntent;
1569 n.deleteIntent = mDeleteIntent;
1570 n.fullScreenIntent = mFullScreenIntent;
1571 n.tickerText = mTickerText;
1572 n.tickerView = makeTickerView();
1573 n.largeIcon = mLargeIcon;
1574 n.sound = mSound;
1575 n.audioStreamType = mAudioStreamType;
1576 n.vibrate = mVibrate;
1577 n.ledARGB = mLedArgb;
1578 n.ledOnMS = mLedOnMs;
1579 n.ledOffMS = mLedOffMs;
1580 n.defaults = mDefaults;
1581 n.flags = mFlags;
Daniel Sandlerb2a1c232012-03-24 10:37:28 -05001582 if (mCanHasIntruder) {
1583 n.intruderView = makeIntruderView(mIntruderActionsShowText);
1584 }
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001585 n.bigContentView = makeBigContentView();
Joe Onorato8d0b6552010-11-22 16:09:29 -08001586 if (mLedOnMs != 0 && mLedOffMs != 0) {
1587 n.flags |= FLAG_SHOW_LIGHTS;
1588 }
1589 if ((mDefaults & DEFAULT_LIGHTS) != 0) {
1590 n.flags |= FLAG_SHOW_LIGHTS;
1591 }
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001592 if (mKindList.size() > 0) {
1593 n.kind = new String[mKindList.size()];
1594 mKindList.toArray(n.kind);
1595 } else {
1596 n.kind = null;
1597 }
1598 n.priority = mPriority;
1599 n.extras = mExtras != null ? new Bundle(mExtras) : null;
Daniel Sandlera0a938c2012-03-15 08:42:37 -04001600 if (mActions.size() > 0) {
1601 n.actions = new Action[mActions.size()];
1602 mActions.toArray(n.actions);
1603 }
Joe Onorato46439ce2010-11-19 13:56:21 -08001604 return n;
1605 }
1606 }
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001607
1608 /**
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001609 * Helper class for generating large-format notifications that include a large image attachment.
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001610 *
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001611 * This class is a "rebuilder": It consumes a Builder object and modifies its behavior, like so:
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001612 * <pre class="prettyprint">
1613 * Notification noti = new Notification.BigPictureStyle(
1614 * new Notification.Builder()
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001615 * .setContentTitle(&quot;New photo from &quot; + sender.toString())
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001616 * .setContentText(subject)
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001617 * .setSmallIcon(R.drawable.new_post)
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001618 * .setLargeIcon(aBitmap))
1619 * .bigPicture(aBigBitmap)
1620 * .build();
1621 * </pre>
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001622 *
1623 * @see Notification#bigContentView
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001624 */
1625 public static class BigPictureStyle {
1626 private Builder mBuilder;
1627 private Bitmap mPicture;
1628
1629 public BigPictureStyle(Builder builder) {
1630 mBuilder = builder;
1631 }
1632
1633 public BigPictureStyle bigPicture(Bitmap b) {
1634 mPicture = b;
1635 return this;
1636 }
1637
1638 private RemoteViews makeBigContentView() {
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001639 RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_big_picture);
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001640
1641 contentView.setImageViewBitmap(R.id.big_picture, mPicture);
1642
1643 return contentView;
1644 }
1645
1646 public Notification build() {
1647 Notification wip = mBuilder.getNotification();
1648 wip.bigContentView = makeBigContentView();
1649 return wip;
1650 }
1651 }
1652
1653 /**
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001654 * Helper class for generating large-format notifications that include a lot of text.
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001655 *
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001656 * This class is a "rebuilder": It consumes a Builder object and modifies its behavior, like so:
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001657 * <pre class="prettyprint">
1658 * Notification noti = new Notification.BigPictureStyle(
1659 * new Notification.Builder()
1660 * .setContentTitle(&quot;New mail from &quot; + sender.toString())
1661 * .setContentText(subject)
1662 * .setSmallIcon(R.drawable.new_mail)
1663 * .setLargeIcon(aBitmap))
1664 * .bigText(aVeryLongString)
1665 * .build();
1666 * </pre>
Daniel Sandler4dfbe832012-04-11 14:51:46 -04001667 *
1668 * @see Notification#bigContentView
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001669 */
1670 public static class BigTextStyle {
1671 private Builder mBuilder;
1672 private CharSequence mBigText;
1673
1674 public BigTextStyle(Builder builder) {
1675 mBuilder = builder;
1676 }
1677
1678 public BigTextStyle bigText(CharSequence cs) {
1679 mBigText = cs;
1680 return this;
1681 }
1682
1683 private RemoteViews makeBigContentView() {
Daniel Sandler96fd7c12012-03-30 16:37:36 -04001684 RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_base);
Daniel Sandlerf3b73432012-03-27 15:01:25 -04001685
1686 contentView.setTextViewText(R.id.big_text, mBigText);
1687 contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
1688 contentView.setTextViewText(R.id.text, ""); // XXX: what do do with this spot?
1689
1690 return contentView;
1691 }
1692
1693 public Notification build() {
1694 Notification wip = mBuilder.getNotification();
1695 wip.bigContentView = makeBigContentView();
1696 return wip;
1697 }
1698 }
Daniel Sandler879c5e02012-04-17 16:46:51 -04001699
1700 /**
1701 * Helper class for generating large-format notifications that include a list of (up to 5) strings.
1702 *
1703 * This class is a "rebuilder": It consumes a Builder object and modifies its behavior, like so:
1704 * <pre class="prettyprint">
1705 * Notification noti = new Notification.DigestStyle(
1706 * new Notification.Builder()
1707 * .setContentTitle(&quot;New mail from &quot; + sender.toString())
1708 * .setContentText(subject)
1709 * .setSmallIcon(R.drawable.new_mail)
1710 * .setLargeIcon(aBitmap))
1711 * .addLine(str1)
1712 * .addLine(str2)
1713 * .build();
1714 * </pre>
1715 *
1716 * @see Notification#bigContentView
1717 */
1718 public static class InboxStyle {
1719 private Builder mBuilder;
1720 private ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(5);
1721
1722 public InboxStyle(Builder builder) {
1723 mBuilder = builder;
1724 }
1725
1726 public InboxStyle addLine(CharSequence cs) {
1727 mTexts.add(cs);
1728 return this;
1729 }
1730
1731 private RemoteViews makeBigContentView() {
1732 RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_inbox);
1733
1734 int[] rowIds = {R.id.inbox_text0, R.id.inbox_text1, R.id.inbox_text2, R.id.inbox_text3, R.id.inbox_text4};
1735
1736 int i=0;
1737 while (i < mTexts.size() && i < rowIds.length) {
1738 CharSequence str = mTexts.get(i);
1739 if (str != null && !str.equals("")) {
1740 contentView.setViewVisibility(rowIds[i], View.VISIBLE);
1741 contentView.setTextViewText(rowIds[i], str);
1742 }
1743 i++;
1744 }
1745
1746 return contentView;
1747 }
1748
1749 public Notification build() {
1750 Notification wip = mBuilder.getNotification();
1751 wip.bigContentView = makeBigContentView();
1752 return wip;
1753 }
1754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755}