NotificationCompat.java revision 120c2dacb760e01e99797ed1d28514c3476dd458
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 public boolean getLocalOnly(Notification n); 271 } 272 273 static class NotificationCompatImplBase implements NotificationCompatImpl { 274 @Override 275 public Notification build(Builder b) { 276 Notification result = b.mNotification; 277 result.setLatestEventInfo(b.mContext, b.mContentTitle, 278 b.mContentText, b.mContentIntent); 279 // translate high priority requests into legacy flag 280 if (b.mPriority > PRIORITY_DEFAULT) { 281 result.flags |= FLAG_HIGH_PRIORITY; 282 } 283 return result; 284 } 285 286 @Override 287 public Bundle getExtras(Notification n) { 288 return null; 289 } 290 291 @Override 292 public boolean getLocalOnly(Notification n) { 293 return false; 294 } 295 } 296 297 static class NotificationCompatImplGingerbread extends NotificationCompatImplBase { 298 @Override 299 public Notification build(Builder b) { 300 Notification result = b.mNotification; 301 result.setLatestEventInfo(b.mContext, b.mContentTitle, 302 b.mContentText, b.mContentIntent); 303 result = NotificationCompatGingerbread.add(result, b.mContext, 304 b.mContentTitle, b.mContentText, b.mContentIntent, b.mFullScreenIntent); 305 // translate high priority requests into legacy flag 306 if (b.mPriority > PRIORITY_DEFAULT) { 307 result.flags |= FLAG_HIGH_PRIORITY; 308 } 309 return result; 310 } 311 } 312 313 static class NotificationCompatImplHoneycomb extends NotificationCompatImplBase { 314 @Override 315 public Notification build(Builder b) { 316 return NotificationCompatHoneycomb.add(b.mContext, b.mNotification, 317 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 318 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon); 319 } 320 } 321 322 static class NotificationCompatImplIceCreamSandwich extends NotificationCompatImplBase { 323 @Override 324 public Notification build(Builder b) { 325 return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification, 326 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 327 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 328 b.mProgressMax, b.mProgress, b.mProgressIndeterminate); 329 } 330 } 331 332 static class NotificationCompatImplJellybean extends NotificationCompatImplBase { 333 @Override 334 public Notification build(Builder b) { 335 NotificationCompatJellybean.Builder builder = new NotificationCompatJellybean.Builder( 336 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 337 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 338 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 339 b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mExtras); 340 addActionsToBuilder(builder, b.mActions); 341 addStyleToBuilderJellybean(builder, b.mStyle); 342 return builder.build(); 343 } 344 345 @Override 346 public Bundle getExtras(Notification n) { 347 return NotificationCompatJellybean.getExtras(n); 348 } 349 350 @Override 351 public boolean getLocalOnly(Notification n) { 352 return NotificationCompatJellybean.getLocalOnly(n); 353 } 354 } 355 356 static class NotificationCompatImplKitKat extends NotificationCompatImplBase { 357 @Override 358 public Notification build(Builder b) { 359 NotificationCompatKitKat.Builder builder = new NotificationCompatKitKat.Builder( 360 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 361 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 362 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 363 b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mPeople, b.mExtras); 364 addActionsToBuilder(builder, b.mActions); 365 addStyleToBuilderJellybean(builder, b.mStyle); 366 return builder.build(); 367 } 368 369 @Override 370 public Bundle getExtras(Notification n) { 371 return NotificationCompatKitKat.getExtras(n); 372 } 373 374 @Override 375 public boolean getLocalOnly(Notification n) { 376 return NotificationCompatKitKat.getLocalOnly(n); 377 } 378 } 379 380 static class NotificationCompatImplApi20 extends NotificationCompatImplBase { 381 @Override 382 public Notification build(Builder b) { 383 NotificationCompatApi20.Builder builder = new NotificationCompatApi20.Builder( 384 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 385 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 386 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 387 b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mCategory, 388 b.mPeople, b.mExtras); 389 addActionsToBuilder(builder, b.mActions); 390 addStyleToBuilderJellybean(builder, b.mStyle); 391 return builder.build(); 392 } 393 394 @Override 395 public Bundle getExtras(Notification n) { 396 return NotificationCompatKitKat.getExtras(n); 397 } 398 399 @Override 400 public boolean getLocalOnly(Notification n) { 401 return NotificationCompatApi20.getLocalOnly(n); 402 } 403 } 404 405 private static void addActionsToBuilder(NotificationBuilderWithActions builder, 406 ArrayList<Action> actions) { 407 for (Action action : actions) { 408 builder.addAction(action.icon, action.title, action.actionIntent); 409 } 410 } 411 412 private static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder, 413 Style style) { 414 if (style != null) { 415 if (style instanceof BigTextStyle) { 416 BigTextStyle bigTextStyle = (BigTextStyle) style; 417 NotificationCompatJellybean.addBigTextStyle(builder, 418 bigTextStyle.mBigContentTitle, 419 bigTextStyle.mSummaryTextSet, 420 bigTextStyle.mSummaryText, 421 bigTextStyle.mBigText); 422 } else if (style instanceof InboxStyle) { 423 InboxStyle inboxStyle = (InboxStyle) style; 424 NotificationCompatJellybean.addInboxStyle(builder, 425 inboxStyle.mBigContentTitle, 426 inboxStyle.mSummaryTextSet, 427 inboxStyle.mSummaryText, 428 inboxStyle.mTexts); 429 } else if (style instanceof BigPictureStyle) { 430 BigPictureStyle bigPictureStyle = (BigPictureStyle) style; 431 NotificationCompatJellybean.addBigPictureStyle(builder, 432 bigPictureStyle.mBigContentTitle, 433 bigPictureStyle.mSummaryTextSet, 434 bigPictureStyle.mSummaryText, 435 bigPictureStyle.mPicture, 436 bigPictureStyle.mBigLargeIcon, 437 bigPictureStyle.mBigLargeIconSet); 438 } 439 } 440 } 441 442 static { 443 // TODO: Replace this if clause when SDK_INT is incremented to 20. 444 if (Build.VERSION.RELEASE.equals("L")) { 445 IMPL = new NotificationCompatImplApi20(); 446 } else if (Build.VERSION.SDK_INT >= 19) { 447 IMPL = new NotificationCompatImplKitKat(); 448 } else if (Build.VERSION.SDK_INT >= 16) { 449 IMPL = new NotificationCompatImplJellybean(); 450 } else if (Build.VERSION.SDK_INT >= 14) { 451 IMPL = new NotificationCompatImplIceCreamSandwich(); 452 } else if (Build.VERSION.SDK_INT >= 11) { 453 IMPL = new NotificationCompatImplHoneycomb(); 454 } else if (Build.VERSION.SDK_INT >= 9) { 455 IMPL = new NotificationCompatImplGingerbread(); 456 } else { 457 IMPL = new NotificationCompatImplBase(); 458 } 459 } 460 461 /** 462 * Builder class for {@link NotificationCompat} objects. Allows easier control over 463 * all the flags, as well as help constructing the typical notification layouts. 464 * <p> 465 * On platform versions that don't offer expanded notifications, methods that depend on 466 * expanded notifications have no effect. 467 * </p> 468 * <p> 469 * For example, action buttons won't appear on platforms prior to Android 4.1. Action 470 * buttons depend on expanded notifications, which are only available in Android 4.1 471 * and later. 472 * <p> 473 * For this reason, you should always ensure that UI controls in a notification are also 474 * available in an {@link android.app.Activity} in your app, and you should always start that 475 * {@link android.app.Activity} when users click the notification. To do this, use the 476 * {@link NotificationCompat.Builder#setContentIntent setContentIntent()} 477 * method. 478 * </p> 479 * 480 */ 481 public static class Builder { 482 Context mContext; 483 484 CharSequence mContentTitle; 485 CharSequence mContentText; 486 PendingIntent mContentIntent; 487 PendingIntent mFullScreenIntent; 488 RemoteViews mTickerView; 489 Bitmap mLargeIcon; 490 CharSequence mContentInfo; 491 int mNumber; 492 int mPriority; 493 boolean mUseChronometer; 494 Style mStyle; 495 CharSequence mSubText; 496 int mProgressMax; 497 int mProgress; 498 boolean mProgressIndeterminate; 499 ArrayList<Action> mActions = new ArrayList<Action>(); 500 boolean mLocalOnly = false; 501 String mCategory; 502 Bundle mExtras; 503 504 Notification mNotification = new Notification(); 505 public ArrayList<String> mPeople; 506 507 /** 508 * Constructor. 509 * 510 * Automatically sets the when field to {@link System#currentTimeMillis() 511 * System.currentTimeMillis()} and the audio stream to the 512 * {@link Notification#STREAM_DEFAULT}. 513 * 514 * @param context A {@link Context} that will be used to construct the 515 * RemoteViews. The Context will not be held past the lifetime of this 516 * Builder object. 517 */ 518 public Builder(Context context) { 519 mContext = context; 520 521 // Set defaults to match the defaults of a Notification 522 mNotification.when = System.currentTimeMillis(); 523 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 524 mPriority = PRIORITY_DEFAULT; 525 mPeople = new ArrayList<String>(); 526 } 527 528 /** 529 * Set the time that the event occurred. Notifications in the panel are 530 * sorted by this time. 531 */ 532 public Builder setWhen(long when) { 533 mNotification.when = when; 534 return this; 535 } 536 537 /** 538 * Show the {@link Notification#when} field as a stopwatch. 539 * 540 * Instead of presenting <code>when</code> as a timestamp, the notification will show an 541 * automatically updating display of the minutes and seconds since <code>when</code>. 542 * 543 * Useful when showing an elapsed time (like an ongoing phone call). 544 * 545 * @see android.widget.Chronometer 546 * @see Notification#when 547 */ 548 public Builder setUsesChronometer(boolean b) { 549 mUseChronometer = b; 550 return this; 551 } 552 553 /** 554 * Set the small icon to use in the notification layouts. Different classes of devices 555 * may return different sizes. See the UX guidelines for more information on how to 556 * design these icons. 557 * 558 * @param icon A resource ID in the application's package of the drawble to use. 559 */ 560 public Builder setSmallIcon(int icon) { 561 mNotification.icon = icon; 562 return this; 563 } 564 565 /** 566 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional 567 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable 568 * LevelListDrawable}. 569 * 570 * @param icon A resource ID in the application's package of the drawble to use. 571 * @param level The level to use for the icon. 572 * 573 * @see android.graphics.drawable.LevelListDrawable 574 */ 575 public Builder setSmallIcon(int icon, int level) { 576 mNotification.icon = icon; 577 mNotification.iconLevel = level; 578 return this; 579 } 580 581 /** 582 * Set the title (first row) of the notification, in a standard notification. 583 */ 584 public Builder setContentTitle(CharSequence title) { 585 mContentTitle = title; 586 return this; 587 } 588 589 /** 590 * Set the text (second row) of the notification, in a standard notification. 591 */ 592 public Builder setContentText(CharSequence text) { 593 mContentText = text; 594 return this; 595 } 596 597 /** 598 * Set the third line of text in the platform notification template. 599 * Don't use if you're also using {@link #setProgress(int, int, boolean)}; 600 * they occupy the same location in the standard template. 601 * <br> 602 * If the platform does not provide large-format notifications, this method has no effect. 603 * The third line of text only appears in expanded view. 604 * <br> 605 */ 606 public Builder setSubText(CharSequence text) { 607 mSubText = text; 608 return this; 609 } 610 611 /** 612 * Set the large number at the right-hand side of the notification. This is 613 * equivalent to setContentInfo, although it might show the number in a different 614 * font size for readability. 615 */ 616 public Builder setNumber(int number) { 617 mNumber = number; 618 return this; 619 } 620 621 /** 622 * Set the large text at the right-hand side of the notification. 623 */ 624 public Builder setContentInfo(CharSequence info) { 625 mContentInfo = info; 626 return this; 627 } 628 629 /** 630 * Set the progress this notification represents, which may be 631 * represented as a {@link android.widget.ProgressBar}. 632 */ 633 public Builder setProgress(int max, int progress, boolean indeterminate) { 634 mProgressMax = max; 635 mProgress = progress; 636 mProgressIndeterminate = indeterminate; 637 return this; 638 } 639 640 /** 641 * Supply a custom RemoteViews to use instead of the standard one. 642 */ 643 public Builder setContent(RemoteViews views) { 644 mNotification.contentView = views; 645 return this; 646 } 647 648 /** 649 * Supply a {@link PendingIntent} to send when the notification is clicked. 650 * If you do not supply an intent, you can now add PendingIntents to individual 651 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent 652 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to 653 * read {@link Notification#contentIntent Notification.contentIntent} for 654 * how to correctly use this. 655 */ 656 public Builder setContentIntent(PendingIntent intent) { 657 mContentIntent = intent; 658 return this; 659 } 660 661 /** 662 * Supply a {@link PendingIntent} to send when the notification is cleared by the user 663 * directly from the notification panel. For example, this intent is sent when the user 664 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This 665 * intent is not sent when the application calls {@link NotificationManager#cancel 666 * NotificationManager.cancel(int)}. 667 */ 668 public Builder setDeleteIntent(PendingIntent intent) { 669 mNotification.deleteIntent = intent; 670 return this; 671 } 672 673 /** 674 * An intent to launch instead of posting the notification to the status bar. 675 * Only for use with extremely high-priority notifications demanding the user's 676 * <strong>immediate</strong> attention, such as an incoming phone call or 677 * alarm clock that the user has explicitly set to a particular time. 678 * If this facility is used for something else, please give the user an option 679 * to turn it off and use a normal notification, as this can be extremely 680 * disruptive. 681 * 682 * @param intent The pending intent to launch. 683 * @param highPriority Passing true will cause this notification to be sent 684 * even if other notifications are suppressed. 685 */ 686 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) { 687 mFullScreenIntent = intent; 688 setFlag(FLAG_HIGH_PRIORITY, highPriority); 689 return this; 690 } 691 692 /** 693 * Set the text that is displayed in the status bar when the notification first 694 * arrives. 695 */ 696 public Builder setTicker(CharSequence tickerText) { 697 mNotification.tickerText = tickerText; 698 return this; 699 } 700 701 /** 702 * Set the text that is displayed in the status bar when the notification first 703 * arrives, and also a RemoteViews object that may be displayed instead on some 704 * devices. 705 */ 706 public Builder setTicker(CharSequence tickerText, RemoteViews views) { 707 mNotification.tickerText = tickerText; 708 mTickerView = views; 709 return this; 710 } 711 712 /** 713 * Set the large icon that is shown in the ticker and notification. 714 */ 715 public Builder setLargeIcon(Bitmap icon) { 716 mLargeIcon = icon; 717 return this; 718 } 719 720 /** 721 * Set the sound to play. It will play on the default stream. 722 */ 723 public Builder setSound(Uri sound) { 724 mNotification.sound = sound; 725 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 726 return this; 727 } 728 729 /** 730 * Set the sound to play. It will play on the stream you supply. 731 * 732 * @see Notification#STREAM_DEFAULT 733 * @see AudioManager for the <code>STREAM_</code> constants. 734 */ 735 public Builder setSound(Uri sound, int streamType) { 736 mNotification.sound = sound; 737 mNotification.audioStreamType = streamType; 738 return this; 739 } 740 741 /** 742 * Set the vibration pattern to use. 743 * 744 * @see android.os.Vibrator for a discussion of the <code>pattern</code> 745 * parameter. 746 */ 747 public Builder setVibrate(long[] pattern) { 748 mNotification.vibrate = pattern; 749 return this; 750 } 751 752 /** 753 * Set the argb value that you would like the LED on the device to blnk, as well as the 754 * rate. The rate is specified in terms of the number of milliseconds to be on 755 * and then the number of milliseconds to be off. 756 */ 757 public Builder setLights(int argb, int onMs, int offMs) { 758 mNotification.ledARGB = argb; 759 mNotification.ledOnMS = onMs; 760 mNotification.ledOffMS = offMs; 761 boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0; 762 mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) | 763 (showLights ? Notification.FLAG_SHOW_LIGHTS : 0); 764 return this; 765 } 766 767 /** 768 * Set whether this is an ongoing notification. 769 * 770 * <p>Ongoing notifications differ from regular notifications in the following ways: 771 * <ul> 772 * <li>Ongoing notifications are sorted above the regular notifications in the 773 * notification panel.</li> 774 * <li>Ongoing notifications do not have an 'X' close button, and are not affected 775 * by the "Clear all" button. 776 * </ul> 777 */ 778 public Builder setOngoing(boolean ongoing) { 779 setFlag(Notification.FLAG_ONGOING_EVENT, ongoing); 780 return this; 781 } 782 783 /** 784 * Set this flag if you would only like the sound, vibrate 785 * and ticker to be played if the notification is not already showing. 786 */ 787 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) { 788 setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce); 789 return this; 790 } 791 792 /** 793 * Setting this flag will make it so the notification is automatically 794 * canceled when the user clicks it in the panel. The PendingIntent 795 * set with {@link #setDeleteIntent} will be broadcast when the notification 796 * is canceled. 797 */ 798 public Builder setAutoCancel(boolean autoCancel) { 799 setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel); 800 return this; 801 } 802 803 /** 804 * Set whether or not this notification is only relevant to the current device. 805 * 806 * <p>Some notifications can be bridged to other devices for remote display. 807 * This hint can be set to recommend this notification not be bridged. 808 */ 809 public Builder setLocalOnly(boolean b) { 810 mLocalOnly = b; 811 return this; 812 } 813 814 /** 815 * Set the notification category. 816 * 817 * <p>Must be one of the predefined notification categories (see the <code>CATEGORY_*</code> 818 * constants in {@link Notification}) that best describes this notification. 819 * May be used by the system for ranking and filtering. 820 */ 821 public Builder setCategory(String category) { 822 mCategory = category; 823 return this; 824 } 825 826 /** 827 * Set the default notification options that will be used. 828 * <p> 829 * The value should be one or more of the following fields combined with 830 * bitwise-or: 831 * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE}, 832 * {@link Notification#DEFAULT_LIGHTS}. 833 * <p> 834 * For all default values, use {@link Notification#DEFAULT_ALL}. 835 */ 836 public Builder setDefaults(int defaults) { 837 mNotification.defaults = defaults; 838 if ((defaults & Notification.DEFAULT_LIGHTS) != 0) { 839 mNotification.flags |= Notification.FLAG_SHOW_LIGHTS; 840 } 841 return this; 842 } 843 844 private void setFlag(int mask, boolean value) { 845 if (value) { 846 mNotification.flags |= mask; 847 } else { 848 mNotification.flags &= ~mask; 849 } 850 } 851 852 /** 853 * Set the relative priority for this notification. 854 * 855 * Priority is an indication of how much of the user's 856 * valuable attention should be consumed by this 857 * notification. Low-priority notifications may be hidden from 858 * the user in certain situations, while the user might be 859 * interrupted for a higher-priority notification. 860 * The system sets a notification's priority based on various factors including the 861 * setPriority value. The effect may differ slightly on different platforms. 862 * 863 * @param pri Relative priority for this notification. Must be one of 864 * the priority constants defined by {@link NotificationCompat}. 865 * Acceptable values range from {@link 866 * NotificationCompat#PRIORITY_MIN} (-2) to {@link 867 * NotificationCompat#PRIORITY_MAX} (2). 868 */ 869 public Builder setPriority(int pri) { 870 mPriority = pri; 871 return this; 872 } 873 874 /** 875 * Add a person that is relevant to this notification. 876 * 877 * @see Notification#EXTRA_PEOPLE 878 */ 879 public Builder addPerson(String handle) { 880 mPeople.add(handle); 881 return this; 882 } 883 884 /** 885 * Merge additional metadata into this notification. 886 * 887 * <p>Values within the Bundle will replace existing extras values in this Builder. 888 * 889 * @see Notification#extras 890 */ 891 public Builder addExtras(Bundle bag) { 892 if (mExtras == null) { 893 mExtras = new Bundle(bag); 894 } else { 895 mExtras.putAll(bag); 896 } 897 return this; 898 } 899 900 /** 901 * Set metadata for this notification. 902 * 903 * <p>A reference to the Bundle is held for the lifetime of this Builder, and the Bundle's 904 * current contents are copied into the Notification each time {@link #build()} is 905 * called. 906 * 907 * <p>Replaces any existing extras values with those from the provided Bundle. 908 * Use {@link #addExtras} to merge in metadata instead. 909 * 910 * @see Notification#extras 911 */ 912 public Builder setExtras(Bundle bag) { 913 mExtras = bag; 914 return this; 915 } 916 917 /** 918 * Get the current metadata Bundle used by this notification Builder. 919 * 920 * <p>The returned Bundle is shared with this Builder. 921 * 922 * <p>The current contents of this Bundle are copied into the Notification each time 923 * {@link #build()} is called. 924 * 925 * @see Notification#extras 926 */ 927 public Bundle getExtras() { 928 if (mExtras == null) { 929 mExtras = new Bundle(); 930 } 931 return mExtras; 932 } 933 934 /** 935 * Add an action to this notification. Actions are typically displayed by 936 * the system as a button adjacent to the notification content. 937 * <br> 938 * Action buttons won't appear on platforms prior to Android 4.1. Action 939 * buttons depend on expanded notifications, which are only available in Android 4.1 940 * and later. To ensure that an action button's functionality is always available, first 941 * implement the functionality in the {@link android.app.Activity} that starts when a user 942 * clicks the notification (see {@link #setContentIntent setContentIntent()}), and then 943 * enhance the notification by implementing the same functionality with 944 * {@link #addAction addAction()}. 945 * 946 * @param icon Resource ID of a drawable that represents the action. 947 * @param title Text describing the action. 948 * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked. 949 */ 950 public Builder addAction(int icon, CharSequence title, PendingIntent intent) { 951 mActions.add(new Action(icon, title, intent)); 952 return this; 953 } 954 955 /** 956 * Add a rich notification style to be applied at build time. 957 * <br> 958 * If the platform does not provide rich notification styles, this method has no effect. The 959 * user will always see the normal notification style. 960 * 961 * @param style Object responsible for modifying the notification style. 962 */ 963 public Builder setStyle(Style style) { 964 if (mStyle != style) { 965 mStyle = style; 966 if (mStyle != null) { 967 mStyle.setBuilder(this); 968 } 969 } 970 return this; 971 } 972 973 /** 974 * @deprecated Use {@link #build()} instead. 975 */ 976 @Deprecated 977 public Notification getNotification() { 978 return IMPL.build(this); 979 } 980 981 /** 982 * Combine all of the options that have been set and return a new {@link Notification} 983 * object. 984 */ 985 public Notification build() { 986 return IMPL.build(this); 987 } 988 } 989 990 /** 991 * An object that can apply a rich notification style to a {@link Notification.Builder} 992 * object. 993 * <br> 994 * If the platform does not provide rich notification styles, methods in this class have no 995 * effect. 996 */ 997 public static abstract class Style { 998 Builder mBuilder; 999 CharSequence mBigContentTitle; 1000 CharSequence mSummaryText; 1001 boolean mSummaryTextSet = false; 1002 1003 public void setBuilder(Builder builder) { 1004 if (mBuilder != builder) { 1005 mBuilder = builder; 1006 if (mBuilder != null) { 1007 mBuilder.setStyle(this); 1008 } 1009 } 1010 } 1011 1012 public Notification build() { 1013 Notification notification = null; 1014 if (mBuilder != null) { 1015 notification = mBuilder.build(); 1016 } 1017 return notification; 1018 } 1019 } 1020 1021 /** 1022 * Helper class for generating large-format notifications that include a large image attachment. 1023 * <br> 1024 * If the platform does not provide large-format notifications, this method has no effect. The 1025 * user will always see the normal notification view. 1026 * <br> 1027 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 1028 * <pre class="prettyprint"> 1029 * Notification noti = new Notification.Builder() 1030 * .setContentTitle("New photo from " + sender.toString()) 1031 * .setContentText(subject) 1032 * .setSmallIcon(R.drawable.new_post) 1033 * .setLargeIcon(aBitmap) 1034 * .setStyle(new Notification.BigPictureStyle() 1035 * .bigPicture(aBigBitmap)) 1036 * .build(); 1037 * </pre> 1038 * 1039 * @see Notification#bigContentView 1040 */ 1041 public static class BigPictureStyle extends Style { 1042 Bitmap mPicture; 1043 Bitmap mBigLargeIcon; 1044 boolean mBigLargeIconSet; 1045 1046 public BigPictureStyle() { 1047 } 1048 1049 public BigPictureStyle(Builder builder) { 1050 setBuilder(builder); 1051 } 1052 1053 /** 1054 * Overrides ContentTitle in the big form of the template. 1055 * This defaults to the value passed to setContentTitle(). 1056 */ 1057 public BigPictureStyle setBigContentTitle(CharSequence title) { 1058 mBigContentTitle = title; 1059 return this; 1060 } 1061 1062 /** 1063 * Set the first line of text after the detail section in the big form of the template. 1064 */ 1065 public BigPictureStyle setSummaryText(CharSequence cs) { 1066 mSummaryText = cs; 1067 mSummaryTextSet = true; 1068 return this; 1069 } 1070 1071 /** 1072 * Provide the bitmap to be used as the payload for the BigPicture notification. 1073 */ 1074 public BigPictureStyle bigPicture(Bitmap b) { 1075 mPicture = b; 1076 return this; 1077 } 1078 1079 /** 1080 * Override the large icon when the big notification is shown. 1081 */ 1082 public BigPictureStyle bigLargeIcon(Bitmap b) { 1083 mBigLargeIcon = b; 1084 mBigLargeIconSet = true; 1085 return this; 1086 } 1087 } 1088 1089 /** 1090 * Helper class for generating large-format notifications that include a lot of text. 1091 * 1092 * <br> 1093 * If the platform does not provide large-format notifications, this method has no effect. The 1094 * user will always see the normal notification view. 1095 * <br> 1096 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 1097 * <pre class="prettyprint"> 1098 * Notification noti = new Notification.Builder() 1099 * .setContentTitle("New mail from " + sender.toString()) 1100 * .setContentText(subject) 1101 * .setSmallIcon(R.drawable.new_mail) 1102 * .setLargeIcon(aBitmap) 1103 * .setStyle(new Notification.BigTextStyle() 1104 * .bigText(aVeryLongString)) 1105 * .build(); 1106 * </pre> 1107 * 1108 * @see Notification#bigContentView 1109 */ 1110 public static class BigTextStyle extends Style { 1111 CharSequence mBigText; 1112 1113 public BigTextStyle() { 1114 } 1115 1116 public BigTextStyle(Builder builder) { 1117 setBuilder(builder); 1118 } 1119 1120 /** 1121 * Overrides ContentTitle in the big form of the template. 1122 * This defaults to the value passed to setContentTitle(). 1123 */ 1124 public BigTextStyle setBigContentTitle(CharSequence title) { 1125 mBigContentTitle = title; 1126 return this; 1127 } 1128 1129 /** 1130 * Set the first line of text after the detail section in the big form of the template. 1131 */ 1132 public BigTextStyle setSummaryText(CharSequence cs) { 1133 mSummaryText = cs; 1134 mSummaryTextSet = true; 1135 return this; 1136 } 1137 1138 /** 1139 * Provide the longer text to be displayed in the big form of the 1140 * template in place of the content text. 1141 */ 1142 public BigTextStyle bigText(CharSequence cs) { 1143 mBigText = cs; 1144 return this; 1145 } 1146 } 1147 1148 /** 1149 * Helper class for generating large-format notifications that include a list of (up to 5) strings. 1150 * 1151 * <br> 1152 * If the platform does not provide large-format notifications, this method has no effect. The 1153 * user will always see the normal notification view. 1154 * <br> 1155 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 1156 * <pre class="prettyprint"> 1157 * Notification noti = new Notification.Builder() 1158 * .setContentTitle("5 New mails from " + sender.toString()) 1159 * .setContentText(subject) 1160 * .setSmallIcon(R.drawable.new_mail) 1161 * .setLargeIcon(aBitmap) 1162 * .setStyle(new Notification.InboxStyle() 1163 * .addLine(str1) 1164 * .addLine(str2) 1165 * .setContentTitle("") 1166 * .setSummaryText("+3 more")) 1167 * .build(); 1168 * </pre> 1169 * 1170 * @see Notification#bigContentView 1171 */ 1172 public static class InboxStyle extends Style { 1173 ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(); 1174 1175 public InboxStyle() { 1176 } 1177 1178 public InboxStyle(Builder builder) { 1179 setBuilder(builder); 1180 } 1181 1182 /** 1183 * Overrides ContentTitle in the big form of the template. 1184 * This defaults to the value passed to setContentTitle(). 1185 */ 1186 public InboxStyle setBigContentTitle(CharSequence title) { 1187 mBigContentTitle = title; 1188 return this; 1189 } 1190 1191 /** 1192 * Set the first line of text after the detail section in the big form of the template. 1193 */ 1194 public InboxStyle setSummaryText(CharSequence cs) { 1195 mSummaryText = cs; 1196 mSummaryTextSet = true; 1197 return this; 1198 } 1199 1200 /** 1201 * Append a line to the digest section of the Inbox notification. 1202 */ 1203 public InboxStyle addLine(CharSequence cs) { 1204 mTexts.add(cs); 1205 return this; 1206 } 1207 } 1208 1209 public static class Action { 1210 public int icon; 1211 public CharSequence title; 1212 public PendingIntent actionIntent; 1213 1214 public Action(int icon_, CharSequence title_, PendingIntent intent_) { 1215 this.icon = icon_; 1216 this.title = title_; 1217 this.actionIntent = intent_; 1218 } 1219 } 1220 1221 /** 1222 * Gets the {@link Notification#extras} field from a notification in a backwards 1223 * compatible manner. Extras field was supported from JellyBean (Api level 16) 1224 * forwards. This function will return null on older api levels. 1225 */ 1226 public static Bundle getExtras(Notification notif) { 1227 return IMPL.getExtras(notif); 1228 } 1229 1230 /** 1231 * Get whether or not this notification is only relevant to the current device. 1232 * 1233 * <p>Some notifications can be bridged to other devices for remote display. 1234 * If this hint is set, it is recommend that this notification not be bridged. 1235 */ 1236 public static boolean getLocalOnly(Notification notif) { 1237 return IMPL.getLocalOnly(notif); 1238 } 1239} 1240