• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=通知
2page.tags=通知
3helpoutsWidget=true
4page.image=/preview/images/notifications-card.png
5
6trainingnavtop=true
7
8@jd:body
9
10<div id="qv-wrapper">
11<div id="qv">
12
13<!-- table of contents -->
14<h2>本文内容包括</h2>
15<ol>
16  <li><a href="#direct">直接回复</a></li>
17  <li><a href="#bundle">捆绑通知</a></li>
18  <li><a href="#custom">自定义视图</a></li>
19  <li><a href="#style">消息样式</a></li>
20</ol>
21
22</div>
23</div>
24
25<p>Android N 引入了一些新 API,允许应用发布具有高度可见性和交互性的通知。
26</p>
27
28<p>Android N 扩展了现有 {@link android.support.v4.app.RemoteInput} 通知 API,以支持手持式设备上的内联回复。
29此功能允许用户从通知栏快速进行回复,无需访问应用。
30</p>
31
32<p>
33  此外,Android N 还允许捆绑类似的通知并将它们显示为一则通知。
34为了实现此功能,Android N 使用现有的 {@link
35  android.support.v4.app.NotificationCompat.Builder#setGroup
36  NotificationCompat.Builder.setGroup()} 方法。用户可以从通知栏展开各通知,并分别对每则通知进行回复和清除等操作。
37
38
39</p>
40
41<p>最后,Android N 还添加了一些新 API,允许您在应用的自定义通知视图中使用系统装饰元素。
42这些 API 可帮助确保通知视图与标准模板的展示效果相一致。
43
44</p>
45
46<p>本文重点介绍您在应用中使用新通知功能时应加以考虑的一些重要变更。
47</p>
48
49<h2 id="direct">直接回复</h2>
50
51<p>利用 Android N 中的直接回复功能,用户可以直接在通知界面内快速回复短信或更新任务列表。
52
53在手持式设备上,可通过通知中另外附加的按钮进行内联回复操作。
54当用户通过键盘回复时,系统会将文本回复附加到您为通知操作指定的 Intent,并将 Intent 发送到手持式设备应用。
55
56
57
58
59
60<img id="fig-reply-button" src="{@docRoot}preview/images/inline-reply.png" srcset="{@docRoot}preview/images/inline-reply.png 1x,
61  {@docRoot}preview/images/inline-reply_2x.png 2x" width="400">
62<p class="img-caption">
63  <strong>图 1.</strong>Android N 添加了 <strong>Reply</strong> 操作按钮。
64
65</p>
66
67<h3>添加内联回复操作</h3>
68
69<p>要创建支持直接回复的通知操作:
70</p>
71
72<ol>
73<li>创建一个可添加到通知操作的 {@link android.support.v4.app.RemoteInput.Builder} 实例。
74
75该类的构造函数接受系统用作文本输入密钥的字符串。
76之后,手持式设备应用使用该密钥检索输入的文本。
77
78
79<pre>
80// Key for the string that's delivered in the action's intent.
81private static final String KEY_TEXT_REPLY = "key_text_reply";
82String replyLabel = getResources().getString(R.string.reply_label);
83RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
84        .setLabel(replyLabel)
85        .build();
86</pre>
87</li>
88<li>使用 <code>addRemoteInput()</code> 向操作附加 {@link android.support.v4.app.RemoteInput} 对象。
89
90
91<pre>
92// Create the reply action and add the remote input.
93Notification.Action action =
94        new Notification.Action.Builder(R.drawable.ic_reply_icon,
95                getString(R.string.label), replyPendingIntent)
96                .addRemoteInput(remoteInput)
97                .build();
98</pre>
99</li>
100
101<li>对通知应用操作并发出通知。
102
103<pre>
104// Build the notification and add the action.
105Notification newMessageNotification =
106        new Notification.Builder(mContext)
107                .setSmallIcon(R.drawable.ic_message)
108                .setContentTitle(getString(R.string.title))
109                .setContentText(getString(R.string.content))
110                .addAction(action))
111                .build();
112
113// Issue the notification.
114NotificationManager notificationManager =
115        NotificationManager.from(mContext);
116notificationManager.notify(notificationId, newMessageNotification);
117
118</pre>
119</li>
120
121</ol>
122
123
124<p> 在触发通知操作时系统提示用户输入回复。
125 </p>
126
127<img id="fig-user-input" src="{@docRoot}preview/images/inline-type-reply.png" srcset="{@docRoot}preview/images/inline-type-reply.png 1x,
128    {@docRoot}preview/images/inline-type-reply_2x.png 2x" width="300">
129<p class="img-caption">
130  <strong>图 2.</strong>用户从通知栏输入文本。
131</p>
132
133<h3>
134  从内联回复检索用户输入
135</h3>
136
137<p>
138  要从通知界面接收用户输入并发送到在回复操作的 Intent 中声明的 Activity:
139
140</p>
141
142<ol>
143  <li>通过传递通知操作的 Intent 作为输入参数来调用 {@link android.support.v4.app.RemoteInput#getResultsFromIntent
144 getResultsFromIntent()}。
145该方法返回含有文本回复的 {@link android.os.Bundle}。
146
147
148    <pre>
149Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
150</pre>
151  </li>
152
153  <li>使用产生的密钥查询捆绑包(提供给 {@link
154 android.support.v4.app.RemoteInput.Builder} 构造函数)。以下代码段说明了方法如何从捆绑包检索输入文本:
155
156
157
158    <pre>
159// Obtain the intent that started this activity by calling
160// Activity.getIntent() and pass it into this method to
161// get the associated string.
162
163private CharSequence getMessageText(Intent intent) {
164    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
165    if (remoteInput != null) {
166        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
167    }
168    return null;
169 }
170</pre>
171  </li>
172
173  <li>使用您为上一项通知提供的相同的通知 ID 来建立和发布另一项通知。
174进度指示器从通知界面消失,以告知用户已回复成功。
175
176在处理这项新通知时,使用被传递到接收器 {@code onReceive()} 方法的上下文。
177
178
179    <pre>
180// Build a new notification, which informs the user that the system
181// handled their interaction with the previous notification.
182Notification repliedNotification =
183        new Notification.Builder(context)
184                .setSmallIcon(R.drawable.ic_message)
185                .setContentText(getString(R.string.replied))
186                .build();
187
188// Issue the new notification.
189NotificationManager notificationManager =
190        NotificationManager.from(context);
191notificationManager.notify(notificationId, repliedNotification);
192</pre>
193  </li>
194</ol>
195
196<p>
197  对于交互式应用(例如聊天),这可以用来在处理检索到的文本时添加其他上下文。
198例如,这些应用可以显示多行聊天记录。
199当用户通过 {@link
200  android.support.v4.app.RemoteInput} 回复时,您可以使用 {@code setRemoteInputHistory()} 方法更新回复历史。
201
202</p>
203
204<p>
205  在应用收到远程输入后,必须更新或取消通知。
206如果用户使用直接回复来对远程更新进行回复,则不可取消通知。
207
208否则,更新通知以显示用户的回复。对于使用 {@code MessagingStyle} 的通知,您应该添加回复来作为最新消息。
209
210当使用其它模板时,您可以将用户的回复追加到远程输入历史。
211
212</p>
213
214<h2 id="bundle">捆绑通知</h2>
215
216<p>Android N 为开发者提供了表示通知队列的新方法:
217 <i>捆绑通知</i>。这类似于 Android Wear 中的<a href="{@docRoot}training/wearables/notifications/stacks.html">通知堆栈</a>功能。
218
219例如,如果应用为接收的消息创建通知,那么在接收到多个消息时,应用会将通知捆绑在一起成为一个群组。
220
221您可以使用现有的 {@link android.support.v4.app.NotificationCompat.Builder#setGroup
222Builder.setGroup()} 方法捆绑类似的通知。
223</p>
224
225<p>
226  通知组对组内的通知施加层次结构。
227  层次结构的顶层是父级通知,其显示该群组的摘要信息。
228用户可以逐步展开通知组,随着用户深入展开,系统将显示更多信息。
229
230当用户展开捆绑包时,系统将显示其所有子通知的更多信息;当用户展开其中一则通知时,系统显示该通知的所有内容。
231
232
233</p>
234
235<img id="fig-bundles" src="{@docRoot}preview/images/bundles.png" srcset="{@docRoot}preview/images/bundles.png 1x,
236          {@docRoot}preview/images/bundles_2x.png 2x" width="300">
237<p class="img-caption">
238  <strong>图 3.</strong>用户可以逐步展开通知组。
239
240</p>
241
242<p class="note">
243  <strong>注:</strong>如果同一应用发送了四条或以上通知,并且未指定分组,系统会自动将它们分到一组。
244
245
246</p>
247
248<p>如需了解如何将通知添加到组,请参阅<a href="{@docRoot}training/wearables/notifications/stacks.html#AddGroup">将各通知添加到组</a>。
249
250</p>
251
252
253<h3 id="best-practices">捆绑通知最佳做法</h3>
254<p>本节提供了有关何时使用通知组而非早期版本 Android 平台中的 {@link android.app.Notification.InboxStyle InboxStyle} 通知的指南。
255
256
257</p>
258
259<h3>何时使用捆绑通知</h3>
260
261<p>只有在您的用例满足以下所有条件时才应使用通知组:
262</p>
263
264<ul>
265  <li>子通知为完整通知,且可以单独显示,无需群组摘要。
266</li>
267  <li>单独显示子通知更合理。例如:
268
269  </li>
270  <ul>
271    <li>子通知可操作,且每个子通知均有特定的操作。</li>
272    <li>子通知中包含用户想要查看的更多信息。</li>
273  </ul>
274</ul>
275
276<p>好的通知组用例示例包括:显示传入消息列表的短信应用,或显示收到的电子邮件列表的电子邮件应用。
277
278</p>
279
280<p>
281适合显示单一通知的用例示例包括:从某一个人收到的单独消息,或以列表表示的单行文本项目。
282
283您可以使用 {@link android.app.Notification.InboxStyle InboxStyle} 或
284{@link android.app.Notification.BigTextStyle BigTextStyle} 实现此功能。
285
286
287</p>
288
289<h3 id ="post">显示捆绑通知</h3>
290
291<p>
292  即使组内仅含有一则子通知,应用也应发布组摘要。
293如果只含有一则通知,系统将取消摘要并直接显示子通知。
294这样可确保用户在滑动切换组内的子通知时,系统仍可以提供一致的用户体验。
295
296
297</p>
298
299<p class="note">
300  <strong>注:</strong>本版本 Android N 目前还无法在仅含一则子通知时取消通知组的摘要。
301我们将在之后版本的 Android N 中添加此功能。
302
303</p>
304
305<h3>扫视通知</h3>
306
307<p>虽然系统通常以群组的方式显示子通知,但您可以进行设置,使其暂时作为<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Heads-up">浮动通知</a>显示。
308
309
310该功能非常实用,因为其允许用户立即访问最近的子通知以及与其相关的操作。
311
312</p>
313
314
315<h3>后向兼容性</h3>
316
317<p>
318  自 Android 5.0(API 级别 21)起,{@link
319  android.app.Notification} API 中就添加了通知组和远程输入,以支持 Android Wear 设备。
320如果您已经使用这些 API 构建通知,则只需验证应用行为是否符合上述指南,并考虑实现 {@code
321  setRemoteInputHistory()}。
322
323
324</p>
325
326<p>
327  为了支持后向兼容性,支持库的 {@link android.support.v4.app.NotificationCompat} 类中提供了相同的 API,以便您构建可在早期 Android 版本中运行的通知。
328
329
330在手持式设备和平板电脑上,用户只能看到摘要通知,因此应用应仍提供收件箱式或类似形式的通知显示模式,以显示群组的全部信息内容。
331
332鉴于 Android Wear 设备允许用户查看所有子通知,包括更早级别平台上的通知,您应在不依赖 API 级别的基础上构建子通知。
333
334
335
336</p>
337
338<h2 id="custom"> 自定义视图</h2>
339<p>从 Android N 开始,您将可以自定义通知视图,同时仍可以使用系统装饰元素,例如通知标头、操作和可展开的布局。
340
341</p>
342
343<p>为启用该功能,Android N 添加了以下 API,以便您样式化自己的自定义视图:
344</p>
345
346<dl>
347<dt>
348{@code DecoratedCustomViewStyle()}</dt>
349<dd> 样式化除媒体通知外的其他通知。
350</dd>
351<dt>
352{@code DecoratedMediaCustomViewStyle()}</dt>
353<dd> 样式化媒体通知。</dd>
354</dl>
355
356<p>如需使用这些新 API,可调用 {@code setStyle()} 方法,并向其传递所需的自定义视图样式。
357</p>
358
359<p>此代码段显示了如何使用 {@code DecoratedCustomViewStyle()} 方法构建自定义通知对象。
360</p>
361
362<pre>
363Notification notification = new Notification.Builder()
364           .setSmallIcon(R.drawable.ic_stat_player)
365           .setLargeIcon(albumArtBitmap))
366           .setCustomContentView(contentView);
367           .setStyle(new Notification.DecoratedCustomViewStyle())
368           .build();
369
370</pre>
371
372<h2 id="style">消息传递样式</h2>
373<p>
374  Android N 引入了一项新的 API 来自定义通知样式。
375  使用 <code>MessageStyle</code> 类,您可以更改在通知中显示的多个标签,包括会话标题、其他消息和通知的内容视图。
376
377
378</p>
379
380<p>
381  以下代码段演示了如何使用 <code>MessageStyle</code> 类来自定义通知样式。
382
383</p>
384
385<pre>
386  Notification notification = new Notification.Builder()
387             .setStyle(new Notification.MessagingStyle("Me")
388                 .setConversationTitle("Team lunch")
389                 .addMessage("Hi", timestamp1, null) // Pass in null for user.
390                 .addMessage("What's up?", timestamp2, "Coworker")
391                 .addMessage("Not much", timestamp3, null)
392                 .addMessage("How about lunch?", timestamp4, "Coworker"));
393</pre>
394