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