NotificationCompat.java revision f021758934b35e3b842c6799344531d7ea2969da
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.widget.RemoteViews; 28import java.util.ArrayList; 29 30public class NotificationCompat { 31 /** 32 * Obsolete flag indicating high-priority notifications; use the priority field instead. 33 * 34 * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value. 35 */ 36 public static final int FLAG_HIGH_PRIORITY = 0x00000080; 37 38 /** 39 * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}. 40 * If your application does not prioritize its own notifications, 41 * use this value for all notifications. 42 */ 43 public static final int PRIORITY_DEFAULT = 0; 44 45 /** 46 * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 47 * for items that are less important. The UI may choose to show 48 * these items smaller, or at a different position in the list, 49 * compared with your app's {@link #PRIORITY_DEFAULT} items. 50 */ 51 public static final int PRIORITY_LOW = -1; 52 53 /** 54 * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)}; 55 * these items might not be shown to the user except under 56 * special circumstances, such as detailed notification logs. 57 */ 58 public static final int PRIORITY_MIN = -2; 59 60 /** 61 * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 62 * for more important notifications or alerts. The UI may choose 63 * to show these items larger, or at a different position in 64 * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items. 65 */ 66 public static final int PRIORITY_HIGH = 1; 67 68 /** 69 * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 70 * for your application's most important items that require the user's 71 * prompt attention or input. 72 */ 73 public static final int PRIORITY_MAX = 2; 74 75 private static final NotificationCompatImpl IMPL; 76 77 interface NotificationCompatImpl { 78 public Notification build(Builder b); 79 } 80 81 static class NotificationCompatImplBase implements NotificationCompatImpl { 82 public Notification build(Builder b) { 83 Notification result = (Notification) b.mNotification; 84 result.setLatestEventInfo(b.mContext, b.mContentTitle, 85 b.mContentText, b.mContentIntent); 86 // translate high priority requests into legacy flag 87 if (b.mPriority > PRIORITY_DEFAULT) { 88 result.flags |= FLAG_HIGH_PRIORITY; 89 } 90 return result; 91 } 92 } 93 94 static class NotificationCompatImplHoneycomb implements NotificationCompatImpl { 95 public Notification build(Builder b) { 96 return NotificationCompatHoneycomb.add(b.mContext, b.mNotification, 97 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 98 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon); 99 } 100 } 101 102 static class NotificationCompatImplIceCreamSandwich implements NotificationCompatImpl { 103 public Notification build(Builder b) { 104 return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification, 105 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 106 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 107 b.mProgressMax, b.mProgress, b.mProgressIndeterminate); 108 } 109 } 110 111 static class NotificationCompatImplJellybean implements NotificationCompatImpl { 112 public Notification build(Builder b) { 113 NotificationCompatJellybean jbBuilder = new NotificationCompatJellybean( 114 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 115 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 116 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 117 b.mUseChronometer, b.mPriority, b.mSubText); 118 for (Action action: b.mActions) { 119 jbBuilder.addAction(action.icon, action.title, action.actionIntent); 120 } 121 if (b.mStyle != null) { 122 if (b.mStyle instanceof BigTextStyle) { 123 BigTextStyle style = (BigTextStyle) b.mStyle; 124 jbBuilder.addBigTextStyle(style.mBigContentTitle, 125 style.mSummaryTextSet, 126 style.mSummaryText, 127 style.mBigText); 128 } else if (b.mStyle instanceof InboxStyle) { 129 InboxStyle style = (InboxStyle) b.mStyle; 130 jbBuilder.addInboxStyle(style.mBigContentTitle, 131 style.mSummaryTextSet, 132 style.mSummaryText, 133 style.mTexts); 134 } else if (b.mStyle instanceof BigPictureStyle) { 135 BigPictureStyle style = (BigPictureStyle) b.mStyle; 136 jbBuilder.addBigPictureStyle(style.mBigContentTitle, 137 style.mSummaryTextSet, 138 style.mSummaryText, 139 style.mPicture); 140 } 141 } 142 return(jbBuilder.build()); 143 } 144 } 145 146 static { 147 if (Build.VERSION.SDK_INT >= 16) { 148 IMPL = new NotificationCompatImplJellybean(); 149 } else if (Build.VERSION.SDK_INT >= 13) { 150 IMPL = new NotificationCompatImplIceCreamSandwich(); 151 } else if (Build.VERSION.SDK_INT >= 11) { 152 IMPL = new NotificationCompatImplHoneycomb(); 153 } else { 154 IMPL = new NotificationCompatImplBase(); 155 } 156 } 157 158 /** 159 * Builder class for {@link Notification} objects. Allows easier control over 160 * all the flags, as well as help constructing the typical notification layouts. 161 */ 162 public static class Builder { 163 Context mContext; 164 165 CharSequence mContentTitle; 166 CharSequence mContentText; 167 PendingIntent mContentIntent; 168 PendingIntent mFullScreenIntent; 169 RemoteViews mTickerView; 170 Bitmap mLargeIcon; 171 CharSequence mContentInfo; 172 int mNumber; 173 int mPriority; 174 boolean mUseChronometer; 175 Style mStyle; 176 CharSequence mSubText; 177 int mProgressMax; 178 int mProgress; 179 boolean mProgressIndeterminate; 180 ArrayList<Action> mActions = new ArrayList<Action>(); 181 182 Notification mNotification = new Notification(); 183 184 /** 185 * Constructor. 186 * 187 * Automatically sets the when field to {@link System#currentTimeMillis() 188 * System.currentTimeMillis()} and the audio stream to the 189 * {@link Notification#STREAM_DEFAULT}. 190 * 191 * @param context A {@link Context} that will be used to construct the 192 * RemoteViews. The Context will not be held past the lifetime of this 193 * Builder object. 194 */ 195 public Builder(Context context) { 196 mContext = context; 197 198 // Set defaults to match the defaults of a Notification 199 mNotification.when = System.currentTimeMillis(); 200 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 201 mPriority = PRIORITY_DEFAULT; 202 } 203 204 /** 205 * Set the time that the event occurred. Notifications in the panel are 206 * sorted by this time. 207 */ 208 public Builder setWhen(long when) { 209 mNotification.when = when; 210 return this; 211 } 212 213 /** 214 * Show the {@link Notification#when} field as a stopwatch. 215 * 216 * Instead of presenting <code>when</code> as a timestamp, the notification will show an 217 * automatically updating display of the minutes and seconds since <code>when</code>. 218 * 219 * Useful when showing an elapsed time (like an ongoing phone call). 220 * 221 * @see android.widget.Chronometer 222 * @see Notification#when 223 */ 224 public Builder setUsesChronometer(boolean b) { 225 mUseChronometer = b; 226 return this; 227 } 228 229 /** 230 * Set the small icon to use in the notification layouts. Different classes of devices 231 * may return different sizes. See the UX guidelines for more information on how to 232 * design these icons. 233 * 234 * @param icon A resource ID in the application's package of the drawble to use. 235 */ 236 public Builder setSmallIcon(int icon) { 237 mNotification.icon = icon; 238 return this; 239 } 240 241 /** 242 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional 243 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable 244 * LevelListDrawable}. 245 * 246 * @param icon A resource ID in the application's package of the drawble to use. 247 * @param level The level to use for the icon. 248 * 249 * @see android.graphics.drawable.LevelListDrawable 250 */ 251 public Builder setSmallIcon(int icon, int level) { 252 mNotification.icon = icon; 253 mNotification.iconLevel = level; 254 return this; 255 } 256 257 /** 258 * Set the title (first row) of the notification, in a standard notification. 259 */ 260 public Builder setContentTitle(CharSequence title) { 261 mContentTitle = title; 262 return this; 263 } 264 265 /** 266 * Set the text (second row) of the notification, in a standard notification. 267 */ 268 public Builder setContentText(CharSequence text) { 269 mContentText = text; 270 return this; 271 } 272 273 /** 274 * Set the third line of text in the platform notification template. 275 * Don't use if you're also using {@link #setProgress(int, int, boolean)}; 276 * they occupy the same location in the standard template. 277 */ 278 public Builder setSubText(CharSequence text) { 279 mSubText = text; 280 return this; 281 } 282 283 /** 284 * Set the large number at the right-hand side of the notification. This is 285 * equivalent to setContentInfo, although it might show the number in a different 286 * font size for readability. 287 */ 288 public Builder setNumber(int number) { 289 mNumber = number; 290 return this; 291 } 292 293 /** 294 * Set the large text at the right-hand side of the notification. 295 */ 296 public Builder setContentInfo(CharSequence info) { 297 mContentInfo = info; 298 return this; 299 } 300 301 /** 302 * Set the progress this notification represents, which may be 303 * represented as a {@link android.widget.ProgressBar}. 304 */ 305 public Builder setProgress(int max, int progress, boolean indeterminate) { 306 mProgressMax = max; 307 mProgress = progress; 308 mProgressIndeterminate = indeterminate; 309 return this; 310 } 311 312 /** 313 * Supply a custom RemoteViews to use instead of the standard one. 314 */ 315 public Builder setContent(RemoteViews views) { 316 mNotification.contentView = views; 317 return this; 318 } 319 320 /** 321 * Supply a {@link PendingIntent} to send when the notification is clicked. 322 * If you do not supply an intent, you can now add PendingIntents to individual 323 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent 324 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to 325 * read {@link Notification#contentIntent Notification.contentIntent} for 326 * how to correctly use this. 327 */ 328 public Builder setContentIntent(PendingIntent intent) { 329 mContentIntent = intent; 330 return this; 331 } 332 333 /** 334 * Supply a {@link PendingIntent} to send when the notification is cleared by the user 335 * directly from the notification panel. For example, this intent is sent when the user 336 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This 337 * intent is not sent when the application calls {@link NotificationManager#cancel 338 * NotificationManager.cancel(int)}. 339 */ 340 public Builder setDeleteIntent(PendingIntent intent) { 341 mNotification.deleteIntent = intent; 342 return this; 343 } 344 345 /** 346 * An intent to launch instead of posting the notification to the status bar. 347 * Only for use with extremely high-priority notifications demanding the user's 348 * <strong>immediate</strong> attention, such as an incoming phone call or 349 * alarm clock that the user has explicitly set to a particular time. 350 * If this facility is used for something else, please give the user an option 351 * to turn it off and use a normal notification, as this can be extremely 352 * disruptive. 353 * 354 * @param intent The pending intent to launch. 355 * @param highPriority Passing true will cause this notification to be sent 356 * even if other notifications are suppressed. 357 */ 358 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) { 359 mFullScreenIntent = intent; 360 setFlag(FLAG_HIGH_PRIORITY, highPriority); 361 return this; 362 } 363 364 /** 365 * Set the text that is displayed in the status bar when the notification first 366 * arrives. 367 */ 368 public Builder setTicker(CharSequence tickerText) { 369 mNotification.tickerText = tickerText; 370 return this; 371 } 372 373 /** 374 * Set the text that is displayed in the status bar when the notification first 375 * arrives, and also a RemoteViews object that may be displayed instead on some 376 * devices. 377 */ 378 public Builder setTicker(CharSequence tickerText, RemoteViews views) { 379 mNotification.tickerText = tickerText; 380 mTickerView = views; 381 return this; 382 } 383 384 /** 385 * Set the large icon that is shown in the ticker and notification. 386 */ 387 public Builder setLargeIcon(Bitmap icon) { 388 mLargeIcon = icon; 389 return this; 390 } 391 392 /** 393 * Set the sound to play. It will play on the default stream. 394 */ 395 public Builder setSound(Uri sound) { 396 mNotification.sound = sound; 397 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 398 return this; 399 } 400 401 /** 402 * Set the sound to play. It will play on the stream you supply. 403 * 404 * @see #STREAM_DEFAULT 405 * @see AudioManager for the <code>STREAM_</code> constants. 406 */ 407 public Builder setSound(Uri sound, int streamType) { 408 mNotification.sound = sound; 409 mNotification.audioStreamType = streamType; 410 return this; 411 } 412 413 /** 414 * Set the vibration pattern to use. 415 * 416 * @see android.os.Vibrator for a discussion of the <code>pattern</code> 417 * parameter. 418 */ 419 public Builder setVibrate(long[] pattern) { 420 mNotification.vibrate = pattern; 421 return this; 422 } 423 424 /** 425 * Set the argb value that you would like the LED on the device to blnk, as well as the 426 * rate. The rate is specified in terms of the number of milliseconds to be on 427 * and then the number of milliseconds to be off. 428 */ 429 public Builder setLights(int argb, int onMs, int offMs) { 430 mNotification.ledARGB = argb; 431 mNotification.ledOnMS = onMs; 432 mNotification.ledOffMS = offMs; 433 boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0; 434 mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) | 435 (showLights ? Notification.FLAG_SHOW_LIGHTS : 0); 436 return this; 437 } 438 439 /** 440 * Set whether this is an ongoing notification. 441 * 442 * <p>Ongoing notifications differ from regular notifications in the following ways: 443 * <ul> 444 * <li>Ongoing notifications are sorted above the regular notifications in the 445 * notification panel.</li> 446 * <li>Ongoing notifications do not have an 'X' close button, and are not affected 447 * by the "Clear all" button. 448 * </ul> 449 */ 450 public Builder setOngoing(boolean ongoing) { 451 setFlag(Notification.FLAG_ONGOING_EVENT, ongoing); 452 return this; 453 } 454 455 /** 456 * Set this flag if you would only like the sound, vibrate 457 * and ticker to be played if the notification is not already showing. 458 */ 459 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) { 460 setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce); 461 return this; 462 } 463 464 /** 465 * Setting this flag will make it so the notification is automatically 466 * canceled when the user clicks it in the panel. The PendingIntent 467 * set with {@link #setDeleteIntent} will be broadcast when the notification 468 * is canceled. 469 */ 470 public Builder setAutoCancel(boolean autoCancel) { 471 setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel); 472 return this; 473 } 474 475 /** 476 * Set the default notification options that will be used. 477 * <p> 478 * The value should be one or more of the following fields combined with 479 * bitwise-or: 480 * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE}, 481 * {@link Notification#DEFAULT_LIGHTS}. 482 * <p> 483 * For all default values, use {@link Notification#DEFAULT_ALL}. 484 */ 485 public Builder setDefaults(int defaults) { 486 mNotification.defaults = defaults; 487 if ((defaults & Notification.DEFAULT_LIGHTS) != 0) { 488 mNotification.flags |= Notification.FLAG_SHOW_LIGHTS; 489 } 490 return this; 491 } 492 493 private void setFlag(int mask, boolean value) { 494 if (value) { 495 mNotification.flags |= mask; 496 } else { 497 mNotification.flags &= ~mask; 498 } 499 } 500 501 /** 502 * Set the relative priority for this notification. 503 * 504 * Priority is an indication of how much of the user's 505 * valuable attention should be consumed by this 506 * notification. Low-priority notifications may be hidden from 507 * the user in certain situations, while the user might be 508 * interrupted for a higher-priority notification. The system 509 * will make a determination about how to interpret 510 * notification priority as described in MUMBLE MUMBLE. 511 */ 512 public Builder setPriority(int pri) { 513 mPriority = pri; 514 return this; 515 } 516 517 /** 518 * Add an action to this notification. Actions are typically displayed by 519 * the system as a button adjacent to the notification content. 520 * 521 * @param icon Resource ID of a drawable that represents the action. 522 * @param title Text describing the action. 523 * @param intent PendingIntent to be fired when the action is invoked. 524 */ 525 public Builder addAction(int icon, CharSequence title, PendingIntent intent) { 526 mActions.add(new Action(icon, title, intent)); 527 return this; 528 } 529 530 /** 531 * Add a rich notification style to be applied at build time. 532 * 533 * @param style Object responsible for modifying the notification style. 534 */ 535 public Builder setStyle(Style style) { 536 if (mStyle != style) { 537 mStyle = style; 538 if (mStyle != null) { 539 mStyle.setBuilder(this); 540 } 541 } 542 return this; 543 } 544 545 /** 546 * @deprecated Use {@link #build()} instead. 547 */ 548 @Deprecated 549 public Notification getNotification() { 550 return (Notification) IMPL.build(this); 551 } 552 553 /** 554 * Combine all of the options that have been set and return a new {@link Notification} 555 * object. 556 */ 557 public Notification build() { 558 return (Notification) IMPL.build(this); 559 } 560 } 561 562 /** 563 * An object that can apply a rich notification style to a {@link Notification.Builder} 564 * object. 565 */ 566 public static abstract class Style 567 { 568 Builder mBuilder; 569 CharSequence mBigContentTitle; 570 CharSequence mSummaryText; 571 boolean mSummaryTextSet = false; 572 573 public void setBuilder(Builder builder) { 574 if (mBuilder != builder) { 575 mBuilder = builder; 576 if (mBuilder != null) { 577 mBuilder.setStyle(this); 578 } 579 } 580 } 581 582 public Notification build() { 583 Notification notification = null; 584 if (mBuilder != null) { 585 notification = mBuilder.build(); 586 } 587 return notification; 588 } 589 } 590 591 /** 592 * Helper class for generating large-format notifications that include a large image attachment. 593 * 594 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 595 * <pre class="prettyprint"> 596 * Notification noti = new Notification.Builder() 597 * .setContentTitle("New photo from " + sender.toString()) 598 * .setContentText(subject) 599 * .setSmallIcon(R.drawable.new_post) 600 * .setLargeIcon(aBitmap) 601 * .setStyle(new Notification.BigPictureStyle() 602 * .bigPicture(aBigBitmap)) 603 * .build(); 604 * </pre> 605 * 606 * @see Notification#bigContentView 607 */ 608 public static class BigPictureStyle extends Style { 609 Bitmap mPicture; 610 611 public BigPictureStyle() { 612 } 613 614 public BigPictureStyle(Builder builder) { 615 setBuilder(builder); 616 } 617 618 /** 619 * Overrides ContentTitle in the big form of the template. 620 * This defaults to the value passed to setContentTitle(). 621 */ 622 public BigPictureStyle setBigContentTitle(CharSequence title) { 623 mBigContentTitle = title; 624 return this; 625 } 626 627 /** 628 * Set the first line of text after the detail section in the big form of the template. 629 */ 630 public BigPictureStyle setSummaryText(CharSequence cs) { 631 mSummaryText = cs; 632 mSummaryTextSet = true; 633 return this; 634 } 635 636 public BigPictureStyle bigPicture(Bitmap b) { 637 mPicture = b; 638 return this; 639 } 640 } 641 642 /** 643 * Helper class for generating large-format notifications that include a lot of text. 644 * 645 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 646 * <pre class="prettyprint"> 647 * Notification noti = new Notification.Builder() 648 * .setContentTitle("New mail from " + sender.toString()) 649 * .setContentText(subject) 650 * .setSmallIcon(R.drawable.new_mail) 651 * .setLargeIcon(aBitmap) 652 * .setStyle(new Notification.BigTextStyle() 653 * .bigText(aVeryLongString)) 654 * .build(); 655 * </pre> 656 * 657 * @see Notification#bigContentView 658 */ 659 public static class BigTextStyle extends Style { 660 CharSequence mBigText; 661 662 public BigTextStyle() { 663 } 664 665 public BigTextStyle(Builder builder) { 666 setBuilder(builder); 667 } 668 669 /** 670 * Overrides ContentTitle in the big form of the template. 671 * This defaults to the value passed to setContentTitle(). 672 */ 673 public BigTextStyle setBigContentTitle(CharSequence title) { 674 mBigContentTitle = title; 675 return this; 676 } 677 678 /** 679 * Set the first line of text after the detail section in the big form of the template. 680 */ 681 public BigTextStyle setSummaryText(CharSequence cs) { 682 mSummaryText = cs; 683 mSummaryTextSet = true; 684 return this; 685 } 686 687 public BigTextStyle bigText(CharSequence cs) { 688 mBigText = cs; 689 return this; 690 } 691 } 692 693 /** 694 * Helper class for generating large-format notifications that include a list of (up to 5) strings. 695 * 696 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 697 * <pre class="prettyprint"> 698 * Notification noti = new Notification.Builder() 699 * .setContentTitle("5 New mails from " + sender.toString()) 700 * .setContentText(subject) 701 * .setSmallIcon(R.drawable.new_mail) 702 * .setLargeIcon(aBitmap) 703 * .setStyle(new Notification.InboxStyle() 704 * .addLine(str1) 705 * .addLine(str2) 706 * .setContentTitle("") 707 * .setSummaryText("+3 more")) 708 * .build(); 709 * </pre> 710 * 711 * @see Notification#bigContentView 712 */ 713 public static class InboxStyle extends Style { 714 ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(); 715 716 public InboxStyle() { 717 } 718 719 public InboxStyle(Builder builder) { 720 setBuilder(builder); 721 } 722 723 /** 724 * Overrides ContentTitle in the big form of the template. 725 * This defaults to the value passed to setContentTitle(). 726 */ 727 public InboxStyle setBigContentTitle(CharSequence title) { 728 mBigContentTitle = title; 729 return this; 730 } 731 732 /** 733 * Set the first line of text after the detail section in the big form of the template. 734 */ 735 public InboxStyle setSummaryText(CharSequence cs) { 736 mSummaryText = cs; 737 mSummaryTextSet = true; 738 return this; 739 } 740 741 public InboxStyle addLine(CharSequence cs) { 742 mTexts.add(cs); 743 return this; 744 } 745 } 746 747 public static class Action { 748 public int icon; 749 public CharSequence title; 750 public PendingIntent actionIntent; 751 752 public Action(int icon_, CharSequence title_, PendingIntent intent_) { 753 this.icon = icon_; 754 this.title = title_; 755 this.actionIntent = intent_; 756 } 757 } 758} 759