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