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