| page.title=通知 |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>本文内容</h2> |
| <ol> |
| <li><a href="#Design">设计注意事项</a></li> |
| <li><a href="#CreateNotification">创建通知</a> |
| <ol> |
| <li><a href="#Required">必需的通知内容</a></li> |
| <li><a href="#Optional">可选通知内容和设置</a></li> |
| <li><a href="#Actions">通知操作</a></li> |
| <li><a href="#Priority">通知优先级</a></li> |
| <li><a href="#SimpleNotification">创建简单通知</a></li> |
| <li><a href="#ApplyStyle">将扩展布局应用于通知</a></li> |
| <li><a href="#Compatibility">处理兼容性</a></li> |
| </ol> |
| </li> |
| <li><a href="#Managing">管理通知</a> |
| <ol> |
| <li><a href="#Updating">更新通知</a></li> |
| <li><a href="#Removing">删除通知</a></li> |
| </ol> |
| </li> |
| <li><a href="#NotificationResponse">启动 Activity 时保留导航</a> |
| <ol> |
| <li><a href="#DirectEntry">设置常规 Activity PendingIntent</a></li> |
| <li><a href="#ExtendedNotification">设置特殊 Activity PendingIntent</a></li> |
| </ol> |
| </li> |
| <li><a href="#Progress">在通知中显示进度</a> |
| <ol> |
| <li><a href="#FixedProgress">显示持续时间固定的进度指示器</a></li> |
| <li><a href="#ActivityIndicator">显示持续 Activity 指示器</a></li> |
| </ol> |
| </li> |
| <li><a href="#metadata">通知元数据</a></li> |
| <li><a href="#Heads-up">浮动通知</a></li> |
| <li><a href="#lockscreenNotification">锁定屏幕通知</a></li> |
| <ol> |
| <li><a href="#visibility">设置可见性</a></li> |
| <li><a href="#controllingMedia">在锁定屏幕上控制媒体播放</a></li> |
| </ol> |
| <li><a href="#CustomNotification">自定义通知布局</a></li> |
| </ol> |
| |
| <h2>关键类</h2> |
| <ol> |
| <li>{@link android.app.NotificationManager}</li> |
| <li>{@link android.support.v4.app.NotificationCompat}</li> |
| </ol> |
| <h2>视频</h2> |
| <ol> |
| <li> |
| <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&feature=player_detailpage#t=1672s"> |
| 4.1 中的通知</a> |
| </li> |
| </ol> |
| <h2>另请参阅</h2> |
| <ol> |
| <li> |
| <a href="{@docRoot}design/patterns/notifications.html">Android 设计:通知</a> |
| </li> |
| </ol> |
| </div> |
| </div> |
| <p> |
| 通知是您可以在应用的常规 |
| UI |
| 外部向用户显示的消息。当您告知系统发出通知时,它将先以图标的形式显示在<strong>通知区域</strong>中。用户可以打开<strong>抽屉式通知栏</strong>查看通知的详细信息。 |
| 通知区域和抽屉式通知栏均是由系统控制的区域,用户可以随时查看。 |
| |
| </p> |
| <img id="figure1" src="{@docRoot}images/ui/notifications/notification_area.png" height="" alt="" /> |
| <p class="img-caption"> |
| <strong>图 1. </strong>通知区域中的通知。 |
| </p> |
| <img id="figure2" src="{@docRoot}images/ui/notifications/notification_drawer.png" width="280px" alt="" /> |
| <p class="img-caption"> |
| <strong>图 2. </strong>抽屉式通知栏中的通知。 |
| </p> |
| |
| <p class="note"><strong>注:</strong>除非特别注明,否则本指南均引用版本 |
| 4 <a href="{@docRoot}tools/support-library/index.html">支持库</a>中的 {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} |
| 类。Android |
| 3.0(API 级别 11)中已添加类 |
| {@link android.app.Notification.Builder Notification.Builder}。</p> |
| |
| <h2 id="Design">设计注意事项</h2> |
| |
| <p>作为 Android 用户界面的一个重要组成部分,通知具有自己的设计指导方针。Android |
| 5.0(API 级别 21)中引入的材料设计变更尤为重要,您应查阅<a href="{@docRoot}training/material/index.html">材料设计</a>培训资料了解详细信息。 |
| |
| 要了解如何设计通知及其交互,请阅读<a href="{@docRoot}design/patterns/notifications.html">通知</a>设计指南。 |
| </p> |
| |
| <h2 id="CreateNotification">创建通知</h2> |
| |
| <p>您可以在 |
| {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} |
| 对象中为通知指定 UI 信息和操作。要创建通知,请调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#build NotificationCompat.Builder.build()},它将返回包含您的具体规范的 |
| {@link android.app.Notification} 对象。要发出通知,请通过调用 |
| {@link android.app.NotificationManager#notify NotificationManager.notify()} 将 {@link android.app.Notification} |
| 对象传递给系统。</p> |
| |
| <h3 id="Required">必需的通知内容</h3> |
| <p> |
| {@link android.app.Notification} 对象必须包含以下内容:<em></em> |
| </p> |
| <ul> |
| <li> |
| 小图标,由 |
| {@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()} 设置 |
| </li> |
| <li> |
| 标题,由 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()} 设置 |
| </li> |
| <li> |
| 详细文本,由 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()} 设置 |
| </li> |
| </ul> |
| <h3 id="Optional">可选通知内容和设置</h3> |
| <p> |
| 所有其他通知设置和内容都是可选的。如需了解有关它们的更多详情,请参阅 |
| {@link android.support.v4.app.NotificationCompat.Builder} 参考文档。 |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="Actions">通知操作</h3> |
| <p> |
| 尽管通知操作都是可选的,但是您至少应向通知添加一个操作。 |
| 操作允许用户直接从通知转到应用中的 |
| {@link android.app.Activity},他们可在其中查看一个或多个事件或执行进一步的操作。 |
| |
| </p> |
| <p> |
| 一个通知可以提供多个操作。您应该始终定义一个当用户点击通知时会触发的操作;通常,此操作会在应用中打开 |
| {@link android.app.Activity}。 |
| 您也可以向通知添加按钮来执行其他操作,例如,暂停闹铃或立即答复短信;此功能自 |
| Android |
| 4.1 起可用。如果使用其他操作按钮,则您还必须使这些按钮的功能在应用的 |
| {@link android.app.Activity} |
| 中可用;请参阅<a href="#Compatibility">处理兼容性</a>部分,以了解更多详情。 |
| </p> |
| <p> |
| 在 {@link android.app.Notification} 内部,操作本身由 |
| {@link android.app.PendingIntent} 定义,后者包含在应用中启动 |
| {@link android.app.Activity} |
| 的 {@link android.content.Intent}。要将 |
| {@link android.app.PendingIntent} 与手势相关联,请调用 |
| {@link android.support.v4.app.NotificationCompat.Builder} 的适当方法。例如,如果您要在用户点击抽屉式通知栏中的通知文本时启动 |
| {@link android.app.Activity},则可通过调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()} |
| 来添加 {@link android.app.PendingIntent}。 |
| </p> |
| <p> |
| 在用户点击通知时启动 {@link android.app.Activity} |
| 是最常见的操作场景。此外,您还可以在用户清除通知时启动 |
| {@link android.app.Activity}。在 Android 4.1 及更高版本中,您可以通过操作按钮启动 |
| {@link android.app.Activity}。如需了解更多信息,请阅读参考指南的 |
| {@link android.support.v4.app.NotificationCompat.Builder} 部分。 |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="Priority">通知优先级</h3> |
| <p> |
| 您可以根据需要设置通知的优先级。优先级充当一个提示,提醒设备 |
| UI 应该如何显示通知。 |
| 要设置通知的优先级,请调用 {@link |
| android.support.v4.app.NotificationCompat.Builder#setPriority(int) |
| NotificationCompat.Builder.setPriority()} 并传入一个 {@link |
| android.support.v4.app.NotificationCompat} 优先级常量。有五个优先级别,范围从 {@link |
| android.support.v4.app.NotificationCompat#PRIORITY_MIN} (-2) 到 {@link |
| android.support.v4.app.NotificationCompat#PRIORITY_MAX} (2);如果未设置,则优先级默认为 {@link |
| android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT} (0)。 |
| |
| |
| </p> |
| <p> 有关设置适当优先级别的信息,请参阅<a href="{@docRoot}design/patterns/notifications.html">通知</a>设计指南中的“正确设置和管理通知优先级”。 |
| |
| |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="SimpleNotification">创建简单通知</h3> |
| <p> |
| 以下代码段说明了一个指定某项 Activity 在用户点击通知时打开的简单通知。 |
| 请注意,该代码将创建 |
| {@link android.support.v4.app.TaskStackBuilder} 对象并使用它来为操作创建 |
| {@link android.app.PendingIntent}。<a href="#NotificationResponse">启动 Activity 时保留导航</a>部分对此模式做了更详尽的阐述: |
| |
| |
| </p> |
| <pre> |
| NotificationCompat.Builder mBuilder = |
| new NotificationCompat.Builder(this) |
| .setSmallIcon(R.drawable.notification_icon) |
| .setContentTitle("My notification") |
| .setContentText("Hello World!"); |
| // Creates an explicit intent for an Activity in your app |
| Intent resultIntent = new Intent(this, ResultActivity.class); |
| |
| // The stack builder object will contain an artificial back stack for the |
| // started Activity. |
| // This ensures that navigating backward from the Activity leads out of |
| // your application to the Home screen. |
| TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); |
| // Adds the back stack for the Intent (but not the Intent itself) |
| stackBuilder.addParentStack(ResultActivity.class); |
| // Adds the Intent that starts the Activity to the top of the stack |
| stackBuilder.addNextIntent(resultIntent); |
| PendingIntent resultPendingIntent = |
| stackBuilder.getPendingIntent( |
| 0, |
| PendingIntent.FLAG_UPDATE_CURRENT |
| ); |
| mBuilder.setContentIntent(resultPendingIntent); |
| NotificationManager mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| // mId allows you to update the notification later on. |
| mNotificationManager.notify(mId, mBuilder.build()); |
| </pre> |
| <p>就这么简单。您的用户现已收到通知。</p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="ApplyStyle">将扩展布局应用于通知</h3> |
| <p> |
| 要使通知出现在展开视图中,请先创建一个带有所需普通视图选项的 |
| {@link android.support.v4.app.NotificationCompat.Builder} |
| 对象。接下来,调用以扩展布局对象作为其参数的 {@link android.support.v4.app.NotificationCompat.Builder#setStyle |
| Builder.setStyle()}。 |
| </p> |
| <p> |
| 请记住,扩展通知在 Android 4.1 之前的平台上不可用。要了解如何处理针对 |
| Android 4.1 及更早版本平台的通知,请阅读<a href="#Compatibility">处理兼容性</a>部分。 |
| |
| </p> |
| <p> |
| 例如,以下代码段演示了如何更改在前面的代码段中创建的通知,以便使用扩展布局: |
| |
| </p> |
| <pre> |
| NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) |
| .setSmallIcon(R.drawable.notification_icon) |
| .setContentTitle("Event tracker") |
| .setContentText("Events received") |
| NotificationCompat.InboxStyle inboxStyle = |
| new NotificationCompat.InboxStyle(); |
| String[] events = new String[6]; |
| // Sets a title for the Inbox in expanded layout |
| inboxStyle.setBigContentTitle("Event tracker details:"); |
| ... |
| // Moves events into the expanded layout |
| for (int i=0; i < events.length; i++) { |
| |
| inboxStyle.addLine(events[i]); |
| } |
| // Moves the expanded layout object into the notification object. |
| mBuilder.setStyle(inBoxStyle); |
| ... |
| // Issue the notification here. |
| </pre> |
| |
| <h3 id="Compatibility">处理兼容性</h3> |
| |
| <p> |
| 并非所有通知功能都可用于某特定版本,即便用于设置这些功能的方法位于支持库类 |
| {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} |
| 中也是如此。 |
| 例如,依赖于扩展通知的操作按钮仅会显示在 Android |
| 4.1 及更高版本的系统中,这是因为扩展通知本身仅在 |
| Android 4.1 及更高版本的系统中可用。 |
| </p> |
| <p> |
| 为了确保最佳兼容性,请使用 |
| {@link android.support.v4.app.NotificationCompat NotificationCompat} 及其子类(特别是 |
| {@link android.support.v4.app.NotificationCompat.Builder |
| NotificationCompat.Builder})创建通知。此外,在实现通知时,请遵循以下流程: |
| </p> |
| <ol> |
| <li> |
| 为所有用户提供通知的全部功能,无论他们使用何种版本的 Android 系统。 |
| 为此,请验证是否可从应用的 |
| {@link android.app.Activity} 中获得所有功能。要执行此操作,您可能需要添加新的 |
| {@link android.app.Activity}。 |
| <p> |
| 例如,若要使用 |
| {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} 提供停止和启动媒体播放的控件,请先在应用的 |
| {@link android.app.Activity} |
| 中实现此控件。 |
| </p> |
| </li> |
| <li> |
| 确保所有用户均可通过点击通知启动 {@link android.app.Activity} 来获得该Activity中的功能。 |
| 为此,请为 |
| {@link android.app.Activity} |
| 创建 {@link android.app.PendingIntent}。调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent |
| setContentIntent()} 以将 {@link android.app.PendingIntent} 添加到通知。 |
| </li> |
| <li> |
| 现在,将要使用的扩展通知功能添加到通知。请记住,您添加的任何功能还必须在用户点击通知时启动的 |
| {@link android.app.Activity} |
| 中可用。 |
| </li> |
| </ol> |
| |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="Managing">管理通知</h2> |
| <p> |
| 当您需要为同一类型的事件多次发出同一通知时,应避免创建全新的通知, |
| 而是应考虑通过更改之前通知的某些值和/或为其添加某些值来更新通知。 |
| |
| </p> |
| <p> |
| 例如,Gmail 通过增加未读消息计数并将每封电子邮件的摘要添加到通知,通知用户收到了新的电子邮件。 |
| 这称为“堆叠”通知;<a href="{@docRoot}design/patterns/notifications.html">通知</a>设计指南对此进行了更详尽的描述。 |
| |
| |
| </p> |
| <p class="note"> |
| <strong>注:</strong>此 |
| Gmail 功能需要“收件箱”扩展布局,该布局是自 Android 4.1 版本起可用的扩展通知功能的一部分。 |
| </p> |
| <p> |
| 下文介绍如何更新和删除通知。 |
| </p> |
| <h3 id="Updating">更新通知</h3> |
| <p> |
| 要将通知设置为能够更新,请通过调用 |
| {@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()} 发出带有通知 ID 的通知。 |
| 要在发出之后更新此通知,请更新或创建 |
| {@link android.support.v4.app.NotificationCompat.Builder} |
| 对象,从该对象构建 {@link android.app.Notification} 对象,并发出与之前所用 ID 相同的 |
| {@link android.app.Notification}。如果之前的通知仍然可见,则系统会根据 |
| {@link android.app.Notification} |
| 对象的内容更新该通知。相反,如果之前的通知已被清除,系统则会创建一个新通知。 |
| |
| </p> |
| <p> |
| 以下代码段演示了经过更新以反映所发生事件数量的通知。 |
| 它将通知堆叠并显示摘要: |
| </p> |
| <pre> |
| mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| // Sets an ID for the notification, so it can be updated |
| int notifyID = 1; |
| mNotifyBuilder = new NotificationCompat.Builder(this) |
| .setContentTitle("New Message") |
| .setContentText("You've received new messages.") |
| .setSmallIcon(R.drawable.ic_notify_status) |
| numMessages = 0; |
| // Start of a loop that processes data and then notifies the user |
| ... |
| mNotifyBuilder.setContentText(currentText) |
| .setNumber(++numMessages); |
| // Because the ID remains unchanged, the existing notification is |
| // updated. |
| mNotificationManager.notify( |
| notifyID, |
| mNotifyBuilder.build()); |
| ... |
| </pre> |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="Removing">删除通知</h3> |
| <p> |
| 除非发生以下情况之一,否则通知仍然可见: |
| </p> |
| <ul> |
| <li> |
| 用户单独或通过使用“全部清除”清除了该通知(如果通知可以清除)。 |
| |
| </li> |
| <li> |
| 用户点击通知,且您在创建通知时调用了 |
| {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()}。 |
| |
| </li> |
| <li> |
| 您针对特定的通知 ID 调用了 |
| {@link android.app.NotificationManager#cancel(int) cancel()}。此方法还会删除当前通知。 |
| </li> |
| <li> |
| 您调用了 |
| {@link android.app.NotificationManager#cancelAll() cancelAll()} 方法,该方法将删除之前发出的所有通知。 |
| </li> |
| </ul> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="NotificationResponse">启动 Activity 时保留导航</h2> |
| <p> |
| 从通知中启动 |
| {@link android.app.Activity} 时,您必须保留用户的预期导航体验。 <i> </i> 点击“返回”应该使用户将应用的正常工作流回退到主屏幕,而点击“最新动态”则应将 |
| <i> </i> {@link android.app.Activity} 显示为单独的任务。 |
| 要保留导航体验,您应该在全新任务中启动 |
| {@link android.app.Activity}。如何设置 |
| {@link android.app.PendingIntent} 以获得全新任务取决于正在启动的 |
| {@link android.app.Activity} 的性质。一般有两种情况: |
| </p> |
| <dl> |
| <dt> |
| 常规 Activity |
| </dt> |
| <dd> |
| 您要启动的 |
| {@link android.app.Activity} 是应用的正常工作流的一部分。在这种情况下,请设置 {@link android.app.PendingIntent} |
| 以启动全新任务并为 |
| {@link android.app.PendingIntent}提供返回栈,这将重现应用的正常“返回”行为。 <i> </i> |
| <p> |
| Gmail 应用中的通知演示了这一点。点击一封电子邮件消息的通知时,您将看到消息具体内容。 |
| 触摸<b>返回</b>将使您从 |
| Gmail 回退到主屏幕,就好像您是从主屏幕(而不是通知)进入 |
| Gmail 一样。 |
| </p> |
| <p> |
| 无论您触摸通知时处于哪个应用,都会发生这种情况。 |
| 例如,如果您在 |
| Gmail 中撰写消息时点击了一封电子邮件的通知,则会立即转到该电子邮件。 <i> </i> |
| 触摸“返回”会依次转到收件箱和主屏幕,而不是转到您在撰写的邮件。 |
| |
| </p> |
| </dd> |
| <dt> |
| 特殊 Activity |
| </dt> |
| <dd> |
| 仅当从通知中启动时,用户才会看到此 {@link android.app.Activity}。 |
| 从某种意义上说,{@link android.app.Activity} |
| 是通过提供很难显示在通知本身中的信息来扩展通知。对于这种情况,请将 |
| {@link android.app.PendingIntent} 设置为在全新任务中启动。但是,由于启动的 |
| {@link android.app.Activity} |
| 不是应用 Activity 流程的一部分,因此无需创建返回栈。点击“返回”仍会将用户带到主屏幕。<i></i> |
| |
| </dd> |
| </dl> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="DirectEntry">设置常规 Activity PendingIntent</h3> |
| <p> |
| 要设置可启动直接进入 {@link android.app.Activity} 的 |
| {@link android.app.PendingIntent},请执行以下步骤: |
| </p> |
| <ol> |
| <li> |
| 在清单文件中定义应用的 {@link android.app.Activity} 层次结构。 |
| <ol style="list-style-type: lower-alpha;"> |
| <li> |
| 添加对 Android 4.0.3 及更低版本的支持。为此,请通过添加 |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a></code> |
| 元素作为 |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>的子项来指定正在启动的 |
| {@link android.app.Activity} 的父项。 |
| <p> |
| 对于此元素,请设置 |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code>。 |
| 设置 |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="<parent_activity_name>"</code>,其中,<code><parent_activity_name></code> |
| 是父 |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| 元素的 |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code> |
| 值。请参阅下面的 XML 示例。 |
| </p> |
| </li> |
| <li> |
| 同样添加对 Android 4.1 及更高版本的支持。为此,请将 |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code> |
| 属性添加到正在启动的 |
| {@link android.app.Activity} 的 |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 元素中。 |
| </li> |
| </ol> |
| <p> |
| 最终的 XML 应如下所示: |
| </p> |
| <pre> |
| <activity |
| android:name=".MainActivity" |
| android:label="@string/app_name" > |
| <intent-filter> |
| <action android:name="android.intent.action.MAIN" /> |
| <category android:name="android.intent.category.LAUNCHER" /> |
| </intent-filter> |
| </activity> |
| <activity |
| android:name=".ResultActivity" |
| android:parentActivityName=".MainActivity"> |
| <meta-data |
| android:name="android.support.PARENT_ACTIVITY" |
| android:value=".MainActivity"/> |
| </activity> |
| </pre> |
| </li> |
| <li> |
| 根据可启动 |
| {@link android.app.Activity} 的 {@link android.content.Intent} 创建返回栈: |
| <ol style="list-style-type: lower-alpha;"> |
| <li> |
| 创建 {@link android.content.Intent} 以启动 {@link android.app.Activity}。 |
| </li> |
| <li> |
| 通过调用 {@link android.app.TaskStackBuilder#create |
| TaskStackBuilder.create()} 创建堆栈生成器。 |
| </li> |
| <li> |
| 通过调用 |
| {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} 将返回栈添加到堆栈生成器。 |
| 对于在清单文件中所定义层次结构内的每个 |
| {@link android.app.Activity},返回栈均包含可启动 {@link android.app.Activity} 的 |
| {@link android.content.Intent} 对象。此方法还会添加一些可在全新任务中启动堆栈的标志。 |
| |
| <p class="note"> |
| <strong>注:</strong>尽管 |
| {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} |
| 的参数是对已启动 |
| {@link android.app.Activity} 的引用,但是方法调用不会添加可启动 {@link android.app.Activity} 的 |
| {@link android.content.Intent},而是留待下一步进行处理。 |
| </p> |
| </li> |
| <li> |
| 通过调用 |
| {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()},添加可从通知中启动 {@link android.app.Activity} |
| 的 {@link android.content.Intent}。 |
| 将在第一步中创建的 {@link android.content.Intent} |
| 作为 |
| {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()} 的参数传递。 |
| </li> |
| <li> |
| 如需,请通过调用 {@link android.support.v4.app.TaskStackBuilder#editIntentAt |
| TaskStackBuilder.editIntentAt()} 向堆栈中的 {@link android.content.Intent} |
| 对象添加参数。有时,需要确保目标 {@link android.app.Activity} 在用户使用“返回”导航回它时会显示有意义的数据。 |
| |
| <i> </i> |
| </li> |
| <li> |
| 通过调用 |
| {@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()} 获得此返回栈的 {@link android.app.PendingIntent}。 |
| 然后,您可以使用此 {@link android.app.PendingIntent} 作为 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent |
| setContentIntent()} 的参数。 |
| </li> |
| </ol> |
| </li> |
| </ol> |
| <p> |
| 以下代码段演示了该流程: |
| </p> |
| <pre> |
| ... |
| Intent resultIntent = new Intent(this, ResultActivity.class); |
| TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); |
| // Adds the back stack |
| stackBuilder.addParentStack(ResultActivity.class); |
| // Adds the Intent to the top of the stack |
| stackBuilder.addNextIntent(resultIntent); |
| // Gets a PendingIntent containing the entire back stack |
| PendingIntent resultPendingIntent = |
| stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); |
| ... |
| NotificationCompat.Builder builder = new NotificationCompat.Builder(this); |
| builder.setContentIntent(resultPendingIntent); |
| NotificationManager mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| mNotificationManager.notify(id, builder.build()); |
| </pre> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="ExtendedNotification">设置特殊 Activity PendingIntent</h3> |
| <p> |
| 下文介绍如何设置特殊 Activity |
| {@link android.app.PendingIntent}。 |
| </p> |
| <p> |
| 特殊 |
| {@link android.app.Activity} 无需返回栈,因此您不必在清单文件中定义其 |
| {@link android.app.Activity} 层次结构,也不必调用 |
| {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} |
| 来构建返回栈。取而代之的是,您可使用清单文件设置 |
| {@link android.app.Activity} 任务选项,并通过调用 {@link android.app.PendingIntent#getActivity getActivity()} |
| 创建 {@link android.app.PendingIntent}: |
| </p> |
| <ol> |
| <li> |
| 在清单文件中,将以下属性添加到 {@link android.app.Activity} 的 |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| 元素 |
| <dl> |
| <dt> |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code> |
| </dt> |
| <dd> |
| Activity 的完全限定类名。 |
| </dd> |
| <dt> |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code> |
| </dt> |
| <dd> |
| 与您在代码中设置的 |
| {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} |
| 标志相结合,这可确保此 {@link android.app.Activity} |
| 不会进入应用的默认任务。任何具有应用默认关联的现有任务均不受影响。 |
| |
| </dd> |
| <dt> |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code> |
| </dt> |
| <dd> |
| <i> </i>将新任务从“最新动态”中排除,这样用户就不会在无意中导航回它。 |
| |
| </dd> |
| </dl> |
| <p> |
| 以下代码段显示了该元素: |
| </p> |
| <pre> |
| <activity |
| android:name=".ResultActivity" |
| ... |
| android:launchMode="singleTask" |
| android:taskAffinity="" |
| android:excludeFromRecents="true"> |
| </activity> |
| ... |
| </pre> |
| </li> |
| <li> |
| 构建并发出通知: |
| <ol style="list-style-type: lower-alpha;"> |
| <li> |
| 创建可启动 {@link android.app.Activity}的 |
| {@link android.content.Intent}。 |
| </li> |
| <li> |
| 通过使用 |
| {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} |
| 和 |
| {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK} 标志调用 |
| {@link android.content.Intent#setFlags setFlags()},将 {@link android.app.Activity} 设置为在新的空任务中启动。 |
| </li> |
| <li> |
| 为 {@link android.content.Intent} 设置所需的任何其他选项。 |
| </li> |
| <li> |
| 通过调用 |
| {@link android.app.PendingIntent#getActivity getActivity()} 从 {@link android.content.Intent} 中创建 {@link android.app.PendingIntent}。 |
| 然后,您可以使用此 {@link android.app.PendingIntent} 作为 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent |
| setContentIntent()} 的参数。 |
| </li> |
| </ol> |
| <p> |
| 以下代码段演示了该流程: |
| </p> |
| <pre> |
| // Instantiate a Builder object. |
| NotificationCompat.Builder builder = new NotificationCompat.Builder(this); |
| // Creates an Intent for the Activity |
| Intent notifyIntent = |
| new Intent(this, ResultActivity.class); |
| // Sets the Activity to start in a new, empty task |
| notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
| | Intent.FLAG_ACTIVITY_CLEAR_TASK); |
| // Creates the PendingIntent |
| PendingIntent notifyPendingIntent = |
| PendingIntent.getActivity( |
| this, |
| 0, |
| notifyIntent, |
| PendingIntent.FLAG_UPDATE_CURRENT |
| ); |
| |
| // Puts the PendingIntent into the notification builder |
| builder.setContentIntent(notifyPendingIntent); |
| // Notifications are issued by sending them to the |
| // NotificationManager system service. |
| NotificationManager mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| // Builds an anonymous Notification object from the builder, and |
| // passes it to the NotificationManager |
| mNotificationManager.notify(id, builder.build()); |
| </pre> |
| </li> |
| </ol> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="Progress">在通知中显示进度</h2> |
| <p> |
| 通知可能包括动画形式的进度指示器,向用户显示正在进行的操作状态。 |
| 如果您可以估计操作所需的时间以及任意时刻的完成进度,则使用“限定”形式的指示器(进度栏)。 |
| |
| 如果无法估计操作的时长,则使用“非限定”形式的指示器(Activity 指示器)。 |
| |
| </p> |
| <p> |
| 平台的 |
| {@link android.widget.ProgressBar} 类实现中显示有进度指示器。 |
| </p> |
| <p> |
| 要在 Android 4.0 及更高版本的平台上使用进度指示器,需调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}。对于早期版本,您必须创建包括 {@link android.widget.ProgressBar} |
| 视图的自定义通知布局。 |
| |
| </p> |
| <p> |
| 下文介绍如何使用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} 在通知中显示进度。 |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="FixedProgress">显示持续时间固定的进度指示器</h3> |
| <p> |
| 要显示限定形式的进度栏,请通过调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress |
| setProgress(max, progress, false)} 将进度栏添加到通知,然后发出通知。随着操作继续进行,递增 |
| <code>progress</code> 并更新通知。操作结束时, |
| <code>progress</code> 应该等于 <code>max</code>。调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} |
| 的常见方法是将 <code>max</code> 设置为 100,然后将 <code>progress</code> |
| 作为操作的“完成百分比”值递增。 |
| </p> |
| <p> |
| 您可以在操作完成后仍保留显示进度栏,也可以将其删除。无论哪种情况,都请记住更新通知文本以显示操作已完成。 |
| |
| 要删除进度栏,请调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress |
| setProgress(0, 0, false)}。例如: |
| </p> |
| <pre> |
| ... |
| mNotifyManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| mBuilder = new NotificationCompat.Builder(this); |
| mBuilder.setContentTitle("Picture Download") |
| .setContentText("Download in progress") |
| .setSmallIcon(R.drawable.ic_notification); |
| // Start a lengthy operation in a background thread |
| new Thread( |
| new Runnable() { |
| @Override |
| public void run() { |
| int incr; |
| // Do the "lengthy" operation 20 times |
| for (incr = 0; incr <= 100; incr+=5) { |
| // Sets the progress indicator to a max value, the |
| // current completion percentage, and "determinate" |
| // state |
| mBuilder.setProgress(100, incr, false); |
| // Displays the progress bar for the first time. |
| mNotifyManager.notify(0, mBuilder.build()); |
| // Sleeps the thread, simulating an operation |
| // that takes time |
| try { |
| // Sleep for 5 seconds |
| Thread.sleep(5*1000); |
| } catch (InterruptedException e) { |
| Log.d(TAG, "sleep failure"); |
| } |
| } |
| // When the loop is finished, updates the notification |
| mBuilder.setContentText("Download complete") |
| // Removes the progress bar |
| .setProgress(0,0,false); |
| mNotifyManager.notify(ID, mBuilder.build()); |
| } |
| } |
| // Starts the thread by calling the run() method in its Runnable |
| ).start(); |
| </pre> |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="ActivityIndicator">显示持续 Activity 指示器</h3> |
| <p> |
| 要显示非限定形式的 Activity 指示器,请使用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)} |
| 将其添加到通知(忽略前两个参数),然后发出通知。这样一来,指示器的样式就与进度栏相同,只是其动画还在继续。 |
| |
| </p> |
| <p> |
| 在操作开始之际发出通知。除非您修改通知,否则动画将一直运行。 |
| 操作完成后,调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)},然后更新通知以删除 Activity 指示器。 |
| |
| 请务必这样做;否则,即使操作完成,动画仍将运行。同时,请记得更改通知文本,以表明操作已完成。 |
| |
| </p> |
| <p> |
| 要了解 Activity 指示器的工作方式,请参阅上述代码段。找到以下几行: |
| </p> |
| <pre> |
| // Sets the progress indicator to a max value, the current completion |
| // percentage, and "determinate" state |
| mBuilder.setProgress(100, incr, false); |
| // Issues the notification |
| mNotifyManager.notify(0, mBuilder.build()); |
| </pre> |
| <p> |
| 将找到的这几行替换为以下几行: |
| </p> |
| <pre> |
| // Sets an activity indicator for an operation of indeterminate length |
| mBuilder.setProgress(0, 0, true); |
| // Issues the notification |
| mNotifyManager.notify(0, mBuilder.build()); |
| </pre> |
| |
| <h2 id="metadata">通知元数据</h2> |
| |
| <p>通知可根据您使用以下 |
| {@link android.support.v4.app.NotificationCompat.Builder} 方法分配的元数据进行排序:</p> |
| |
| <ul> |
| <li>当设备处于“优先”模式时,{@link android.support.v4.app.NotificationCompat.Builder#setCategory(java.lang.String) setCategory()} |
| 会告知系统如何处理应用通知(例如,通知代表传入呼叫、即时消息还是闹铃)。 |
| </li> |
| <li>如果优先级字段设置为 |
| {@code PRIORITY_MAX} 或 {@code PRIORITY_HIGH} 的通知还有声音或振动,则 {@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) setPriority()} |
| 会将其显示在小型浮动窗口中。</li> |
| <li>{@link android.support.v4.app.NotificationCompat.Builder#addPerson(java.lang.String) addPerson()} |
| 允许您向通知添加人员名单。您的应用可以使用此名单指示系统将指定人员发出的通知归成一组,或者将这些人员发出的通知视为更重要的通知。 |
| |
| </li> |
| </ul> |
| |
| <div class="figure" style="width:230px"> |
| <img src="{@docRoot}images/ui/notifications/heads-up.png" alt="" width="" height="" id="figure3" /> |
| <p class="img-caption"> |
| <strong>图 3. </strong>显示浮动通知的全屏 Activity |
| </p> |
| </div> |
| |
| <h2 id="Heads-up">浮动通知</h2> |
| |
| <p>对于 Android 5.0(API 级别 21),当设备处于活动状态时(即,设备未锁定且其屏幕已打开),通知可以显示在小型浮动窗口中(也称为“浮动通知”)。<em></em> |
| |
| 这些通知看上去类似于精简版的通知,只是浮动通知还显示操作按钮。 |
| |
| 用户可以在不离开当前应用的情况下处理或清除浮动通知。 |
| </p> |
| |
| <p>可能触发浮动通知的条件示例包括:</p> |
| |
| <ul> |
| <li>用户的 Activity 处于全屏模式中(应用使用 |
| {@link android.app.Notification#fullScreenIntent}),或者</li> |
| <li>通知具有较高的优先级并使用铃声或振动 |
| </li> |
| </ul> |
| |
| <h2 id="lockscreenNotification">锁定屏幕通知</h2> |
| |
| <p>随着 |
| Android 5.0(API 级别 21)的发布,通知现在还可显示在锁定屏幕上。您的应用可以使用此功能提供媒体播放控件以及其他常用操作。 |
| 用户可以通过“设置”选择是否将通知显示在锁定屏幕上,并且您可以指定您应用中的通知在锁定屏幕上是否可见。 |
| </p> |
| |
| <h3 id="visibility">设置可见性</h3> |
| |
| <p>您的应用可以控制在安全锁定屏幕上显示的通知中可见的详细级别。 |
| 调用 {@link android.support.v4.app.NotificationCompat.Builder#setVisibility(int) setVisibility()} |
| 并指定以下值之一:</p> |
| |
| <ul> |
| <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC} |
| 显示通知的完整内容。</li> |
| <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_SECRET} |
| 不会在锁定屏幕上显示此通知的任何部分。</li> |
| <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} |
| 显示通知图标和内容标题等基本信息,但是隐藏通知的完整内容。</li> |
| </ul> |
| |
| <p>设置 {@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} |
| 后,您还可以提供其中隐藏了某些详细信息的替换版本通知内容。例如,短信 |
| 应用可能会显示一条通知,指出“您有 |
| 3 条新短信”,但是隐藏了短信内容和发件人。<em></em>要提供此替换版本的通知,请先使用 |
| {@link android.support.v4.app.NotificationCompat.Builder} 创建替换通知。创建专用通知对象时,请通过 |
| {@link android.support.v4.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) setPublicVersion()} |
| 方法为其附加替换通知。 |
| </p> |
| |
| <h3 id="controllingMedia">在锁定屏幕上控制媒体播放</h3> |
| |
| <p>在 Android 5.0(API 级别 21)中,锁定屏幕不再基于 |
| {@link android.media.RemoteControlClient}(现已弃用)显示媒体控件。取而代之的是,将 |
| {@link android.app.Notification.MediaStyle} 模板与 |
| {@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()} |
| 方法结合使用,后者可将操作转换为可点击的图标。</p> |
| |
| <p class="note"><strong>注:</strong>该模板和 |
| {@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()} |
| 方法未包含在支持库中,因此这些功能只能在 Android 5.0 及更高版本的系统上运行。</p> |
| |
| <p>要在 Android 5.0 系统的锁定屏幕上显示媒体播放控件,请将可见性设置为 |
| {@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC},如上文所述。然后,添加操作并设置 |
| {@link android.app.Notification.MediaStyle} |
| 模板,如以下示例代码中所述:</p> |
| |
| <pre> |
| Notification notification = new Notification.Builder(context) |
| // Show controls on lock screen even when user hides sensitive content. |
| .setVisibility(Notification.VISIBILITY_PUBLIC) |
| .setSmallIcon(R.drawable.ic_stat_player) |
| // Add media control buttons that invoke intents in your media service |
| .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0 |
| .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1 |
| .addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2 |
| // Apply the media style template |
| .setStyle(new Notification.MediaStyle() |
| .setShowActionsInCompactView(1 /* #1: pause button */) |
| .setMediaSession(mMediaSession.getSessionToken()) |
| .setContentTitle("Wonderful music") |
| .setContentText("My Awesome Band") |
| .setLargeIcon(albumArtBitmap) |
| .build(); |
| </pre> |
| |
| <p class="note"><strong>注:</strong>弃用 {@link android.media.RemoteControlClient} |
| 会对控制媒体产生进一步的影响。如需了解有关用于管理媒体会话和控制播放的新 API 的详细信息,请参阅<a href="{@docRoot}about/versions/android-5.0.html#MediaPlaybackControl">媒体播放控件</a>。 |
| |
| </p> |
| |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="CustomNotification">自定义通知布局</h2> |
| <p> |
| 您可以利用通知框架定义自定义通知布局,由该布局定义通知在 |
| {@link android.widget.RemoteViews} 对象中的外观。 |
| 自定义布局通知类似于常规通知,但是它们是基于 XML 布局文件中所定义的 |
| {@link android.widget.RemoteViews}。 |
| </p> |
| <p> |
| 自定义通知布局的可用高度取决于通知视图。普通视图布局限制为 |
| 64 dp,扩展视图布局限制为 256 dp。 |
| </p> |
| <p> |
| 要定义自定义通知布局,请首先实例化 |
| {@link android.widget.RemoteViews} 对象来扩充 XML 布局文件。然后,调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()},而不是调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()} |
| 等方法。要在自定义通知中设置内容详细信息,请使用 |
| {@link android.widget.RemoteViews} |
| 中的方法设置视图子项的值: |
| </p> |
| <ol> |
| <li> |
| 在单独的文件中为通知创建 XML 布局。您可以根据需要使用任何文件名,但必须使用扩展名 |
| <code>.xml</code>。 |
| </li> |
| <li> |
| 在您的应用中,使用 {@link android.widget.RemoteViews} |
| 方法定义通知的图标和文本。通过调用 |
| {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()} 将此 {@link android.widget.RemoteViews} 对象放入 |
| {@link android.support.v4.app.NotificationCompat.Builder} 中。避免在 |
| {@link android.widget.RemoteViews} 对象上设置背景 |
| {@link android.graphics.drawable.Drawable},因为文本颜色可能使文本变得难以阅读。 |
| </li> |
| </ol> |
| <p> |
| 此外,{@link android.widget.RemoteViews} 类中还有一些方法可供您轻松将 |
| {@link android.widget.Chronometer} 或 {@link android.widget.ProgressBar} |
| 添加到通知布局。如需了解有关为通知创建自定义布局的详细信息,请参阅 |
| {@link android.widget.RemoteViews} 参考文档。 |
| </p> |
| <p class="caution"> |
| <strong>注意:</strong>使用自定义通知布局时,要特别注意确保自定义布局适用于不同的设备方向和分辨率。 |
| 尽管这条建议适用于所有“视图”布局,但对通知尤为重要,因为抽屉式通知栏中的空间非常有限。 |
| |
| 不要让自定义布局过于复杂,同时确保在各种配置中对其进行测试。 |
| |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h4>对自定义通知文本使用样式资源</h4> |
| <p> |
| 始终对自定义通知的文本使用样式资源。通知的背景颜色可能因设备和系统版本的不同而异,使用样式资源有助于您充分考虑到这一点。 |
| |
| 从 |
| Android 2.3 开始,系统定义了标准通知布局文本的样式。若要在面向 Android |
| 2.3 或更高版本系统的多个应用中使用相同样式,则应确保文本在显示背景上可见。 |
| </p> |