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