NotificationCompat.java revision bd2cb3c75b05ede6018d74536ce959940a988021
1/* 2 * Copyright (C) 2012 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.support.v4.app; 18 19import android.app.Notification; 20import android.app.NotificationManager; 21import android.app.PendingIntent; 22import android.content.Context; 23import android.graphics.Bitmap; 24import android.media.AudioManager; 25import android.net.Uri; 26import android.os.Build; 27import android.os.Bundle; 28import android.widget.RemoteViews; 29import java.util.ArrayList; 30 31/** 32 * Helper for accessing features in {@link android.app.Notification} 33 * introduced after API level 4 in a backwards compatible fashion. 34 */ 35public class NotificationCompat { 36 37 /** 38 * Use all default values (where applicable). 39 */ 40 public static final int DEFAULT_ALL = ~0; 41 42 /** 43 * Use the default notification sound. This will ignore any sound set using 44 * {@link Builder#setSound} 45 * 46 * @see Builder#setDefaults 47 */ 48 public static final int DEFAULT_SOUND = 1; 49 50 /** 51 * Use the default notification vibrate. This will ignore any vibrate set using 52 * {@link Builder#setVibrate}. Using phone vibration requires the 53 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission. 54 * 55 * @see Builder#setDefaults 56 */ 57 public static final int DEFAULT_VIBRATE = 2; 58 59 /** 60 * Use the default notification lights. This will ignore the 61 * {@link #FLAG_SHOW_LIGHTS} bit, and values set with {@link Builder#setLights}. 62 * 63 * @see Builder#setDefaults 64 */ 65 public static final int DEFAULT_LIGHTS = 4; 66 67 /** 68 * Use this constant as the value for audioStreamType to request that 69 * the default stream type for notifications be used. Currently the 70 * default stream type is {@link AudioManager#STREAM_NOTIFICATION}. 71 */ 72 public static final int STREAM_DEFAULT = -1; 73 74 /** 75 * Bit set in the Notification flags field when LEDs should be turned on 76 * for this notification. 77 */ 78 public static final int FLAG_SHOW_LIGHTS = 0x00000001; 79 80 /** 81 * Bit set in the Notification flags field if this notification is in 82 * reference to something that is ongoing, like a phone call. It should 83 * not be set if this notification is in reference to something that 84 * happened at a particular point in time, like a missed phone call. 85 */ 86 public static final int FLAG_ONGOING_EVENT = 0x00000002; 87 88 /** 89 * Bit set in the Notification flags field if 90 * the audio will be repeated until the notification is 91 * cancelled or the notification window is opened. 92 */ 93 public static final int FLAG_INSISTENT = 0x00000004; 94 95 /** 96 * Bit set in the Notification flags field if the notification's sound, 97 * vibrate and ticker should only be played if the notification is not already showing. 98 */ 99 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008; 100 101 /** 102 * Bit set in the Notification flags field if the notification should be canceled when 103 * it is clicked by the user. 104 */ 105 public static final int FLAG_AUTO_CANCEL = 0x00000010; 106 107 /** 108 * Bit set in the Notification flags field if the notification should not be canceled 109 * when the user clicks the Clear all button. 110 */ 111 public static final int FLAG_NO_CLEAR = 0x00000020; 112 113 /** 114 * Bit set in the Notification flags field if this notification represents a currently 115 * running service. This will normally be set for you by 116 * {@link android.app.Service#startForeground}. 117 */ 118 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040; 119 120 /** 121 * Obsolete flag indicating high-priority notifications; use the priority field instead. 122 * 123 * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value. 124 */ 125 public static final int FLAG_HIGH_PRIORITY = 0x00000080; 126 127 /** 128 * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}. 129 * If your application does not prioritize its own notifications, 130 * use this value for all notifications. 131 */ 132 public static final int PRIORITY_DEFAULT = 0; 133 134 /** 135 * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 136 * for items that are less important. The UI may choose to show 137 * these items smaller, or at a different position in the list, 138 * compared with your app's {@link #PRIORITY_DEFAULT} items. 139 */ 140 public static final int PRIORITY_LOW = -1; 141 142 /** 143 * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)}; 144 * these items might not be shown to the user except under 145 * special circumstances, such as detailed notification logs. 146 */ 147 public static final int PRIORITY_MIN = -2; 148 149 /** 150 * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 151 * for more important notifications or alerts. The UI may choose 152 * to show these items larger, or at a different position in 153 * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items. 154 */ 155 public static final int PRIORITY_HIGH = 1; 156 157 /** 158 * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 159 * for your application's most important items that require the user's 160 * prompt attention or input. 161 */ 162 public static final int PRIORITY_MAX = 2; 163 164 /** 165 * Notification extras key: this is the title of the notification, 166 * as supplied to {@link Builder#setContentTitle(CharSequence)}. 167 */ 168 public static final String EXTRA_TITLE = "android.title"; 169 170 /** 171 * Notification extras key: this is the title of the notification when shown in expanded form, 172 * e.g. as supplied to {@link BigTextStyle#setBigContentTitle(CharSequence)}. 173 */ 174 public static final String EXTRA_TITLE_BIG = EXTRA_TITLE + ".big"; 175 176 /** 177 * Notification extras key: this is the main text payload, as supplied to 178 * {@link Builder#setContentText(CharSequence)}. 179 */ 180 public static final String EXTRA_TEXT = "android.text"; 181 182 /** 183 * Notification extras key: this is a third line of text, as supplied to 184 * {@link Builder#setSubText(CharSequence)}. 185 */ 186 public static final String EXTRA_SUB_TEXT = "android.subText"; 187 188 /** 189 * Notification extras key: this is a small piece of additional text as supplied to 190 * {@link Builder#setContentInfo(CharSequence)}. 191 */ 192 public static final String EXTRA_INFO_TEXT = "android.infoText"; 193 194 /** 195 * Notification extras key: this is a line of summary information intended to be shown 196 * alongside expanded notifications, as supplied to (e.g.) 197 * {@link BigTextStyle#setSummaryText(CharSequence)}. 198 */ 199 public static final String EXTRA_SUMMARY_TEXT = "android.summaryText"; 200 201 /** 202 * Notification extras key: this is the resource ID of the notification's main small icon, as 203 * supplied to {@link Builder#setSmallIcon(int)}. 204 */ 205 public static final String EXTRA_SMALL_ICON = "android.icon"; 206 207 /** 208 * Notification extras key: this is a bitmap to be used instead of the small icon when showing the 209 * notification payload, as 210 * supplied to {@link Builder#setLargeIcon(android.graphics.Bitmap)}. 211 */ 212 public static final String EXTRA_LARGE_ICON = "android.largeIcon"; 213 214 /** 215 * Notification extras key: this is a bitmap to be used instead of the one from 216 * {@link Builder#setLargeIcon(android.graphics.Bitmap)} when the notification is 217 * shown in its expanded form, as supplied to 218 * {@link BigPictureStyle#bigLargeIcon(android.graphics.Bitmap)}. 219 */ 220 public static final String EXTRA_LARGE_ICON_BIG = EXTRA_LARGE_ICON + ".big"; 221 222 /** 223 * Notification extras key: this is the progress value supplied to 224 * {@link Builder#setProgress(int, int, boolean)}. 225 */ 226 public static final String EXTRA_PROGRESS = "android.progress"; 227 228 /** 229 * Notification extras key: this is the maximum value supplied to 230 * {@link Builder#setProgress(int, int, boolean)}. 231 */ 232 public static final String EXTRA_PROGRESS_MAX = "android.progressMax"; 233 234 /** 235 * Notification extras key: whether the progress bar is indeterminate, supplied to 236 * {@link Builder#setProgress(int, int, boolean)}. 237 */ 238 public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate"; 239 240 /** 241 * Notification extras key: whether the when field set using {@link Builder#setWhen} should 242 * be shown as a count-up timer (specifically a {@link android.widget.Chronometer}) instead 243 * of a timestamp, as supplied to {@link Builder#setUsesChronometer(boolean)}. 244 */ 245 public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer"; 246 247 /** 248 * Notification extras key: this is a bitmap to be shown in {@link BigPictureStyle} expanded 249 * notifications, supplied to {@link BigPictureStyle#bigPicture(android.graphics.Bitmap)}. 250 */ 251 public static final String EXTRA_PICTURE = "android.picture"; 252 253 /** 254 * Notification extras key: An array of CharSequences to show in {@link InboxStyle} expanded 255 * notifications, each of which was supplied to {@link InboxStyle#addLine(CharSequence)}. 256 */ 257 public static final String EXTRA_TEXT_LINES = "android.textLines"; 258 259 /** 260 * Notification extras key: An array of people that this notification relates to, specified 261 * by contacts provider contact URI. 262 */ 263 public static final String EXTRA_PEOPLE = "android.people"; 264 265 private static final NotificationCompatImpl IMPL; 266 267 interface NotificationCompatImpl { 268 public Notification build(Builder b); 269 public Bundle getExtras(Notification n); 270 } 271 272 static class NotificationCompatImplBase implements NotificationCompatImpl { 273 @Override 274 public Notification build(Builder b) { 275 Notification result = b.mNotification; 276 result.setLatestEventInfo(b.mContext, b.mContentTitle, 277 b.mContentText, b.mContentIntent); 278 // translate high priority requests into legacy flag 279 if (b.mPriority > PRIORITY_DEFAULT) { 280 result.flags |= FLAG_HIGH_PRIORITY; 281 } 282 return result; 283 } 284 285 @Override 286 public Bundle getExtras(Notification n) { 287 return null; 288 } 289 } 290 291 static class NotificationCompatImplGingerbread extends NotificationCompatImplBase { 292 @Override 293 public Notification build(Builder b) { 294 Notification result = b.mNotification; 295 result.setLatestEventInfo(b.mContext, b.mContentTitle, 296 b.mContentText, b.mContentIntent); 297 result = NotificationCompatGingerbread.add(result, b.mContext, 298 b.mContentTitle, b.mContentText, b.mContentIntent, b.mFullScreenIntent); 299 // translate high priority requests into legacy flag 300 if (b.mPriority > PRIORITY_DEFAULT) { 301 result.flags |= FLAG_HIGH_PRIORITY; 302 } 303 return result; 304 } 305 } 306 307 static class NotificationCompatImplHoneycomb extends NotificationCompatImplBase { 308 @Override 309 public Notification build(Builder b) { 310 return NotificationCompatHoneycomb.add(b.mContext, b.mNotification, 311 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 312 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon); 313 } 314 } 315 316 static class NotificationCompatImplIceCreamSandwich extends NotificationCompatImplBase { 317 @Override 318 public Notification build(Builder b) { 319 return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification, 320 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 321 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 322 b.mProgressMax, b.mProgress, b.mProgressIndeterminate); 323 } 324 } 325 326 static class NotificationCompatImplJellybean extends NotificationCompatImplBase { 327 @Override 328 public Notification build(Builder b) { 329 NotificationCompatJellybean.Builder builder = new NotificationCompatJellybean.Builder( 330 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 331 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 332 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 333 b.mUseChronometer, b.mPriority, b.mSubText, b.mExtras); 334 addActionsToBuilder(builder, b.mActions); 335 addStyleToBuilderJellybean(builder, b.mStyle); 336 return builder.build(); 337 } 338 339 @Override 340 public Bundle getExtras(Notification n) { 341 return NotificationCompatJellybean.getExtras(n); 342 } 343 } 344 345 static class NotificationCompatImplKitKat extends NotificationCompatImplBase { 346 @Override 347 public Notification build(Builder b) { 348 NotificationCompatKitKat.Builder builder = new NotificationCompatKitKat.Builder( 349 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 350 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 351 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 352 b.mUseChronometer, b.mPriority, b.mSubText, b.mExtras); 353 addActionsToBuilder(builder, b.mActions); 354 addStyleToBuilderJellybean(builder, b.mStyle); 355 return builder.build(); 356 } 357 358 @Override 359 public Bundle getExtras(Notification n) { 360 return NotificationCompatKitKat.getExtras(n); 361 } 362 } 363 364 private static void addActionsToBuilder(NotificationBuilderWithActions builder, 365 ArrayList<Action> actions) { 366 for (Action action : actions) { 367 builder.addAction(action.icon, action.title, action.actionIntent); 368 } 369 } 370 371 private static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder, 372 Style style) { 373 if (style != null) { 374 if (style instanceof BigTextStyle) { 375 BigTextStyle bigTextStyle = (BigTextStyle) style; 376 NotificationCompatJellybean.addBigTextStyle(builder, 377 bigTextStyle.mBigContentTitle, 378 bigTextStyle.mSummaryTextSet, 379 bigTextStyle.mSummaryText, 380 bigTextStyle.mBigText); 381 } else if (style instanceof InboxStyle) { 382 InboxStyle inboxStyle = (InboxStyle) style; 383 NotificationCompatJellybean.addInboxStyle(builder, 384 inboxStyle.mBigContentTitle, 385 inboxStyle.mSummaryTextSet, 386 inboxStyle.mSummaryText, 387 inboxStyle.mTexts); 388 } else if (style instanceof BigPictureStyle) { 389 BigPictureStyle bigPictureStyle = (BigPictureStyle) style; 390 NotificationCompatJellybean.addBigPictureStyle(builder, 391 bigPictureStyle.mBigContentTitle, 392 bigPictureStyle.mSummaryTextSet, 393 bigPictureStyle.mSummaryText, 394 bigPictureStyle.mPicture, 395 bigPictureStyle.mBigLargeIcon, 396 bigPictureStyle.mBigLargeIconSet); 397 } 398 } 399 } 400 401 static { 402 if (Build.VERSION.SDK_INT >= 19) { 403 IMPL = new NotificationCompatImplKitKat(); 404 } else if (Build.VERSION.SDK_INT >= 16) { 405 IMPL = new NotificationCompatImplJellybean(); 406 } else if (Build.VERSION.SDK_INT >= 14) { 407 IMPL = new NotificationCompatImplIceCreamSandwich(); 408 } else if (Build.VERSION.SDK_INT >= 11) { 409 IMPL = new NotificationCompatImplHoneycomb(); 410 } else if (Build.VERSION.SDK_INT >= 9) { 411 IMPL = new NotificationCompatImplGingerbread(); 412 } else { 413 IMPL = new NotificationCompatImplBase(); 414 } 415 } 416 417 /** 418 * Builder class for {@link NotificationCompat} objects. Allows easier control over 419 * all the flags, as well as help constructing the typical notification layouts. 420 * <p> 421 * On platform versions that don't offer expanded notifications, methods that depend on 422 * expanded notifications have no effect. 423 * </p> 424 * <p> 425 * For example, action buttons won't appear on platforms prior to Android 4.1. Action 426 * buttons depend on expanded notifications, which are only available in Android 4.1 427 * and later. 428 * <p> 429 * For this reason, you should always ensure that UI controls in a notification are also 430 * available in an {@link android.app.Activity} in your app, and you should always start that 431 * {@link android.app.Activity} when users click the notification. To do this, use the 432 * {@link NotificationCompat.Builder#setContentIntent setContentIntent()} 433 * method. 434 * </p> 435 * 436 */ 437 public static class Builder { 438 Context mContext; 439 440 CharSequence mContentTitle; 441 CharSequence mContentText; 442 PendingIntent mContentIntent; 443 PendingIntent mFullScreenIntent; 444 RemoteViews mTickerView; 445 Bitmap mLargeIcon; 446 CharSequence mContentInfo; 447 int mNumber; 448 int mPriority; 449 boolean mUseChronometer; 450 Style mStyle; 451 CharSequence mSubText; 452 int mProgressMax; 453 int mProgress; 454 boolean mProgressIndeterminate; 455 ArrayList<Action> mActions = new ArrayList<Action>(); 456 Bundle mExtras; 457 458 Notification mNotification = new Notification(); 459 460 /** 461 * Constructor. 462 * 463 * Automatically sets the when field to {@link System#currentTimeMillis() 464 * System.currentTimeMillis()} and the audio stream to the 465 * {@link Notification#STREAM_DEFAULT}. 466 * 467 * @param context A {@link Context} that will be used to construct the 468 * RemoteViews. The Context will not be held past the lifetime of this 469 * Builder object. 470 */ 471 public Builder(Context context) { 472 mContext = context; 473 474 // Set defaults to match the defaults of a Notification 475 mNotification.when = System.currentTimeMillis(); 476 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 477 mPriority = PRIORITY_DEFAULT; 478 } 479 480 /** 481 * Set the time that the event occurred. Notifications in the panel are 482 * sorted by this time. 483 */ 484 public Builder setWhen(long when) { 485 mNotification.when = when; 486 return this; 487 } 488 489 /** 490 * Show the {@link Notification#when} field as a stopwatch. 491 * 492 * Instead of presenting <code>when</code> as a timestamp, the notification will show an 493 * automatically updating display of the minutes and seconds since <code>when</code>. 494 * 495 * Useful when showing an elapsed time (like an ongoing phone call). 496 * 497 * @see android.widget.Chronometer 498 * @see Notification#when 499 */ 500 public Builder setUsesChronometer(boolean b) { 501 mUseChronometer = b; 502 return this; 503 } 504 505 /** 506 * Set the small icon to use in the notification layouts. Different classes of devices 507 * may return different sizes. See the UX guidelines for more information on how to 508 * design these icons. 509 * 510 * @param icon A resource ID in the application's package of the drawble to use. 511 */ 512 public Builder setSmallIcon(int icon) { 513 mNotification.icon = icon; 514 return this; 515 } 516 517 /** 518 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional 519 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable 520 * LevelListDrawable}. 521 * 522 * @param icon A resource ID in the application's package of the drawble to use. 523 * @param level The level to use for the icon. 524 * 525 * @see android.graphics.drawable.LevelListDrawable 526 */ 527 public Builder setSmallIcon(int icon, int level) { 528 mNotification.icon = icon; 529 mNotification.iconLevel = level; 530 return this; 531 } 532 533 /** 534 * Set the title (first row) of the notification, in a standard notification. 535 */ 536 public Builder setContentTitle(CharSequence title) { 537 mContentTitle = title; 538 return this; 539 } 540 541 /** 542 * Set the text (second row) of the notification, in a standard notification. 543 */ 544 public Builder setContentText(CharSequence text) { 545 mContentText = text; 546 return this; 547 } 548 549 /** 550 * Set the third line of text in the platform notification template. 551 * Don't use if you're also using {@link #setProgress(int, int, boolean)}; 552 * they occupy the same location in the standard template. 553 * <br> 554 * If the platform does not provide large-format notifications, this method has no effect. 555 * The third line of text only appears in expanded view. 556 * <br> 557 */ 558 public Builder setSubText(CharSequence text) { 559 mSubText = text; 560 return this; 561 } 562 563 /** 564 * Set the large number at the right-hand side of the notification. This is 565 * equivalent to setContentInfo, although it might show the number in a different 566 * font size for readability. 567 */ 568 public Builder setNumber(int number) { 569 mNumber = number; 570 return this; 571 } 572 573 /** 574 * Set the large text at the right-hand side of the notification. 575 */ 576 public Builder setContentInfo(CharSequence info) { 577 mContentInfo = info; 578 return this; 579 } 580 581 /** 582 * Set the progress this notification represents, which may be 583 * represented as a {@link android.widget.ProgressBar}. 584 */ 585 public Builder setProgress(int max, int progress, boolean indeterminate) { 586 mProgressMax = max; 587 mProgress = progress; 588 mProgressIndeterminate = indeterminate; 589 return this; 590 } 591 592 /** 593 * Supply a custom RemoteViews to use instead of the standard one. 594 */ 595 public Builder setContent(RemoteViews views) { 596 mNotification.contentView = views; 597 return this; 598 } 599 600 /** 601 * Supply a {@link PendingIntent} to send when the notification is clicked. 602 * If you do not supply an intent, you can now add PendingIntents to individual 603 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent 604 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to 605 * read {@link Notification#contentIntent Notification.contentIntent} for 606 * how to correctly use this. 607 */ 608 public Builder setContentIntent(PendingIntent intent) { 609 mContentIntent = intent; 610 return this; 611 } 612 613 /** 614 * Supply a {@link PendingIntent} to send when the notification is cleared by the user 615 * directly from the notification panel. For example, this intent is sent when the user 616 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This 617 * intent is not sent when the application calls {@link NotificationManager#cancel 618 * NotificationManager.cancel(int)}. 619 */ 620 public Builder setDeleteIntent(PendingIntent intent) { 621 mNotification.deleteIntent = intent; 622 return this; 623 } 624 625 /** 626 * An intent to launch instead of posting the notification to the status bar. 627 * Only for use with extremely high-priority notifications demanding the user's 628 * <strong>immediate</strong> attention, such as an incoming phone call or 629 * alarm clock that the user has explicitly set to a particular time. 630 * If this facility is used for something else, please give the user an option 631 * to turn it off and use a normal notification, as this can be extremely 632 * disruptive. 633 * 634 * @param intent The pending intent to launch. 635 * @param highPriority Passing true will cause this notification to be sent 636 * even if other notifications are suppressed. 637 */ 638 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) { 639 mFullScreenIntent = intent; 640 setFlag(FLAG_HIGH_PRIORITY, highPriority); 641 return this; 642 } 643 644 /** 645 * Set the text that is displayed in the status bar when the notification first 646 * arrives. 647 */ 648 public Builder setTicker(CharSequence tickerText) { 649 mNotification.tickerText = tickerText; 650 return this; 651 } 652 653 /** 654 * Set the text that is displayed in the status bar when the notification first 655 * arrives, and also a RemoteViews object that may be displayed instead on some 656 * devices. 657 */ 658 public Builder setTicker(CharSequence tickerText, RemoteViews views) { 659 mNotification.tickerText = tickerText; 660 mTickerView = views; 661 return this; 662 } 663 664 /** 665 * Set the large icon that is shown in the ticker and notification. 666 */ 667 public Builder setLargeIcon(Bitmap icon) { 668 mLargeIcon = icon; 669 return this; 670 } 671 672 /** 673 * Set the sound to play. It will play on the default stream. 674 */ 675 public Builder setSound(Uri sound) { 676 mNotification.sound = sound; 677 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 678 return this; 679 } 680 681 /** 682 * Set the sound to play. It will play on the stream you supply. 683 * 684 * @see Notification#STREAM_DEFAULT 685 * @see AudioManager for the <code>STREAM_</code> constants. 686 */ 687 public Builder setSound(Uri sound, int streamType) { 688 mNotification.sound = sound; 689 mNotification.audioStreamType = streamType; 690 return this; 691 } 692 693 /** 694 * Set the vibration pattern to use. 695 * 696 * @see android.os.Vibrator for a discussion of the <code>pattern</code> 697 * parameter. 698 */ 699 public Builder setVibrate(long[] pattern) { 700 mNotification.vibrate = pattern; 701 return this; 702 } 703 704 /** 705 * Set the argb value that you would like the LED on the device to blnk, as well as the 706 * rate. The rate is specified in terms of the number of milliseconds to be on 707 * and then the number of milliseconds to be off. 708 */ 709 public Builder setLights(int argb, int onMs, int offMs) { 710 mNotification.ledARGB = argb; 711 mNotification.ledOnMS = onMs; 712 mNotification.ledOffMS = offMs; 713 boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0; 714 mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) | 715 (showLights ? Notification.FLAG_SHOW_LIGHTS : 0); 716 return this; 717 } 718 719 /** 720 * Set whether this is an ongoing notification. 721 * 722 * <p>Ongoing notifications differ from regular notifications in the following ways: 723 * <ul> 724 * <li>Ongoing notifications are sorted above the regular notifications in the 725 * notification panel.</li> 726 * <li>Ongoing notifications do not have an 'X' close button, and are not affected 727 * by the "Clear all" button. 728 * </ul> 729 */ 730 public Builder setOngoing(boolean ongoing) { 731 setFlag(Notification.FLAG_ONGOING_EVENT, ongoing); 732 return this; 733 } 734 735 /** 736 * Set this flag if you would only like the sound, vibrate 737 * and ticker to be played if the notification is not already showing. 738 */ 739 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) { 740 setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce); 741 return this; 742 } 743 744 /** 745 * Setting this flag will make it so the notification is automatically 746 * canceled when the user clicks it in the panel. The PendingIntent 747 * set with {@link #setDeleteIntent} will be broadcast when the notification 748 * is canceled. 749 */ 750 public Builder setAutoCancel(boolean autoCancel) { 751 setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel); 752 return this; 753 } 754 755 /** 756 * Set the default notification options that will be used. 757 * <p> 758 * The value should be one or more of the following fields combined with 759 * bitwise-or: 760 * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE}, 761 * {@link Notification#DEFAULT_LIGHTS}. 762 * <p> 763 * For all default values, use {@link Notification#DEFAULT_ALL}. 764 */ 765 public Builder setDefaults(int defaults) { 766 mNotification.defaults = defaults; 767 if ((defaults & Notification.DEFAULT_LIGHTS) != 0) { 768 mNotification.flags |= Notification.FLAG_SHOW_LIGHTS; 769 } 770 return this; 771 } 772 773 private void setFlag(int mask, boolean value) { 774 if (value) { 775 mNotification.flags |= mask; 776 } else { 777 mNotification.flags &= ~mask; 778 } 779 } 780 781 /** 782 * Set the relative priority for this notification. 783 * 784 * Priority is an indication of how much of the user's 785 * valuable attention should be consumed by this 786 * notification. Low-priority notifications may be hidden from 787 * the user in certain situations, while the user might be 788 * interrupted for a higher-priority notification. 789 * The system sets a notification's priority based on various factors including the 790 * setPriority value. The effect may differ slightly on different platforms. 791 * 792 * @param pri Relative priority for this notification. Must be one of 793 * the priority constants defined by {@link NotificationCompat}. 794 * Acceptable values range from {@link 795 * NotificationCompat#PRIORITY_MIN} (-2) to {@link 796 * NotificationCompat#PRIORITY_MAX} (2). 797 */ 798 public Builder setPriority(int pri) { 799 mPriority = pri; 800 return this; 801 } 802 803 /** 804 * Merge additional metadata into this notification. 805 * 806 * <p>Values within the Bundle will replace existing extras values in this Builder. 807 * 808 * @see Notification#extras 809 */ 810 public Builder addExtras(Bundle bag) { 811 if (mExtras == null) { 812 mExtras = new Bundle(bag); 813 } else { 814 mExtras.putAll(bag); 815 } 816 return this; 817 } 818 819 /** 820 * Set metadata for this notification. 821 * 822 * <p>A reference to the Bundle is held for the lifetime of this Builder, and the Bundle's 823 * current contents are copied into the Notification each time {@link #build()} is 824 * called. 825 * 826 * <p>Replaces any existing extras values with those from the provided Bundle. 827 * Use {@link #addExtras} to merge in metadata instead. 828 * 829 * @see Notification#extras 830 */ 831 public Builder setExtras(Bundle bag) { 832 mExtras = bag; 833 return this; 834 } 835 836 /** 837 * Get the current metadata Bundle used by this notification Builder. 838 * 839 * <p>The returned Bundle is shared with this Builder. 840 * 841 * <p>The current contents of this Bundle are copied into the Notification each time 842 * {@link #build()} is called. 843 * 844 * @see Notification#extras 845 */ 846 public Bundle getExtras() { 847 if (mExtras == null) { 848 mExtras = new Bundle(); 849 } 850 return mExtras; 851 } 852 853 /** 854 * Add an action to this notification. Actions are typically displayed by 855 * the system as a button adjacent to the notification content. 856 * <br> 857 * Action buttons won't appear on platforms prior to Android 4.1. Action 858 * buttons depend on expanded notifications, which are only available in Android 4.1 859 * and later. To ensure that an action button's functionality is always available, first 860 * implement the functionality in the {@link android.app.Activity} that starts when a user 861 * clicks the notification (see {@link #setContentIntent setContentIntent()}), and then 862 * enhance the notification by implementing the same functionality with 863 * {@link #addAction addAction()}. 864 * 865 * @param icon Resource ID of a drawable that represents the action. 866 * @param title Text describing the action. 867 * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked. 868 */ 869 public Builder addAction(int icon, CharSequence title, PendingIntent intent) { 870 mActions.add(new Action(icon, title, intent)); 871 return this; 872 } 873 874 /** 875 * Add a rich notification style to be applied at build time. 876 * <br> 877 * If the platform does not provide rich notification styles, this method has no effect. The 878 * user will always see the normal notification style. 879 * 880 * @param style Object responsible for modifying the notification style. 881 */ 882 public Builder setStyle(Style style) { 883 if (mStyle != style) { 884 mStyle = style; 885 if (mStyle != null) { 886 mStyle.setBuilder(this); 887 } 888 } 889 return this; 890 } 891 892 /** 893 * @deprecated Use {@link #build()} instead. 894 */ 895 @Deprecated 896 public Notification getNotification() { 897 return IMPL.build(this); 898 } 899 900 /** 901 * Combine all of the options that have been set and return a new {@link Notification} 902 * object. 903 */ 904 public Notification build() { 905 return IMPL.build(this); 906 } 907 } 908 909 /** 910 * An object that can apply a rich notification style to a {@link Notification.Builder} 911 * object. 912 * <br> 913 * If the platform does not provide rich notification styles, methods in this class have no 914 * effect. 915 */ 916 public static abstract class Style { 917 Builder mBuilder; 918 CharSequence mBigContentTitle; 919 CharSequence mSummaryText; 920 boolean mSummaryTextSet = false; 921 922 public void setBuilder(Builder builder) { 923 if (mBuilder != builder) { 924 mBuilder = builder; 925 if (mBuilder != null) { 926 mBuilder.setStyle(this); 927 } 928 } 929 } 930 931 public Notification build() { 932 Notification notification = null; 933 if (mBuilder != null) { 934 notification = mBuilder.build(); 935 } 936 return notification; 937 } 938 } 939 940 /** 941 * Helper class for generating large-format notifications that include a large image attachment. 942 * <br> 943 * If the platform does not provide large-format notifications, this method has no effect. The 944 * user will always see the normal notification view. 945 * <br> 946 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 947 * <pre class="prettyprint"> 948 * Notification noti = new Notification.Builder() 949 * .setContentTitle("New photo from " + sender.toString()) 950 * .setContentText(subject) 951 * .setSmallIcon(R.drawable.new_post) 952 * .setLargeIcon(aBitmap) 953 * .setStyle(new Notification.BigPictureStyle() 954 * .bigPicture(aBigBitmap)) 955 * .build(); 956 * </pre> 957 * 958 * @see Notification#bigContentView 959 */ 960 public static class BigPictureStyle extends Style { 961 Bitmap mPicture; 962 Bitmap mBigLargeIcon; 963 boolean mBigLargeIconSet; 964 965 public BigPictureStyle() { 966 } 967 968 public BigPictureStyle(Builder builder) { 969 setBuilder(builder); 970 } 971 972 /** 973 * Overrides ContentTitle in the big form of the template. 974 * This defaults to the value passed to setContentTitle(). 975 */ 976 public BigPictureStyle setBigContentTitle(CharSequence title) { 977 mBigContentTitle = title; 978 return this; 979 } 980 981 /** 982 * Set the first line of text after the detail section in the big form of the template. 983 */ 984 public BigPictureStyle setSummaryText(CharSequence cs) { 985 mSummaryText = cs; 986 mSummaryTextSet = true; 987 return this; 988 } 989 990 /** 991 * Provide the bitmap to be used as the payload for the BigPicture notification. 992 */ 993 public BigPictureStyle bigPicture(Bitmap b) { 994 mPicture = b; 995 return this; 996 } 997 998 /** 999 * Override the large icon when the big notification is shown. 1000 */ 1001 public BigPictureStyle bigLargeIcon(Bitmap b) { 1002 mBigLargeIcon = b; 1003 mBigLargeIconSet = true; 1004 return this; 1005 } 1006 } 1007 1008 /** 1009 * Helper class for generating large-format notifications that include a lot of text. 1010 * 1011 * <br> 1012 * If the platform does not provide large-format notifications, this method has no effect. The 1013 * user will always see the normal notification view. 1014 * <br> 1015 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 1016 * <pre class="prettyprint"> 1017 * Notification noti = new Notification.Builder() 1018 * .setContentTitle("New mail from " + sender.toString()) 1019 * .setContentText(subject) 1020 * .setSmallIcon(R.drawable.new_mail) 1021 * .setLargeIcon(aBitmap) 1022 * .setStyle(new Notification.BigTextStyle() 1023 * .bigText(aVeryLongString)) 1024 * .build(); 1025 * </pre> 1026 * 1027 * @see Notification#bigContentView 1028 */ 1029 public static class BigTextStyle extends Style { 1030 CharSequence mBigText; 1031 1032 public BigTextStyle() { 1033 } 1034 1035 public BigTextStyle(Builder builder) { 1036 setBuilder(builder); 1037 } 1038 1039 /** 1040 * Overrides ContentTitle in the big form of the template. 1041 * This defaults to the value passed to setContentTitle(). 1042 */ 1043 public BigTextStyle setBigContentTitle(CharSequence title) { 1044 mBigContentTitle = title; 1045 return this; 1046 } 1047 1048 /** 1049 * Set the first line of text after the detail section in the big form of the template. 1050 */ 1051 public BigTextStyle setSummaryText(CharSequence cs) { 1052 mSummaryText = cs; 1053 mSummaryTextSet = true; 1054 return this; 1055 } 1056 1057 /** 1058 * Provide the longer text to be displayed in the big form of the 1059 * template in place of the content text. 1060 */ 1061 public BigTextStyle bigText(CharSequence cs) { 1062 mBigText = cs; 1063 return this; 1064 } 1065 } 1066 1067 /** 1068 * Helper class for generating large-format notifications that include a list of (up to 5) strings. 1069 * 1070 * <br> 1071 * If the platform does not provide large-format notifications, this method has no effect. The 1072 * user will always see the normal notification view. 1073 * <br> 1074 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 1075 * <pre class="prettyprint"> 1076 * Notification noti = new Notification.Builder() 1077 * .setContentTitle("5 New mails from " + sender.toString()) 1078 * .setContentText(subject) 1079 * .setSmallIcon(R.drawable.new_mail) 1080 * .setLargeIcon(aBitmap) 1081 * .setStyle(new Notification.InboxStyle() 1082 * .addLine(str1) 1083 * .addLine(str2) 1084 * .setContentTitle("") 1085 * .setSummaryText("+3 more")) 1086 * .build(); 1087 * </pre> 1088 * 1089 * @see Notification#bigContentView 1090 */ 1091 public static class InboxStyle extends Style { 1092 ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(); 1093 1094 public InboxStyle() { 1095 } 1096 1097 public InboxStyle(Builder builder) { 1098 setBuilder(builder); 1099 } 1100 1101 /** 1102 * Overrides ContentTitle in the big form of the template. 1103 * This defaults to the value passed to setContentTitle(). 1104 */ 1105 public InboxStyle setBigContentTitle(CharSequence title) { 1106 mBigContentTitle = title; 1107 return this; 1108 } 1109 1110 /** 1111 * Set the first line of text after the detail section in the big form of the template. 1112 */ 1113 public InboxStyle setSummaryText(CharSequence cs) { 1114 mSummaryText = cs; 1115 mSummaryTextSet = true; 1116 return this; 1117 } 1118 1119 /** 1120 * Append a line to the digest section of the Inbox notification. 1121 */ 1122 public InboxStyle addLine(CharSequence cs) { 1123 mTexts.add(cs); 1124 return this; 1125 } 1126 } 1127 1128 public static class Action { 1129 public int icon; 1130 public CharSequence title; 1131 public PendingIntent actionIntent; 1132 1133 public Action(int icon_, CharSequence title_, PendingIntent intent_) { 1134 this.icon = icon_; 1135 this.title = title_; 1136 this.actionIntent = intent_; 1137 } 1138 } 1139 1140 /** 1141 * Gets the {@link Notification#extras} field from a notification in a backwards 1142 * compatible manner. Extras field was supported from JellyBean (Api level 16) 1143 * forwards. This function will return null on older api levels. 1144 */ 1145 public static Bundle getExtras(Notification notif) { 1146 return IMPL.getExtras(notif); 1147 } 1148} 1149