Android直接回復通知
通知直接回復
Android N/7.0
前言
通知(Notification)可為是Android系統(tǒng)中富含特色的一個功能慎陵,從Android的第一個版本到Android N,通知這個功能也發(fā)生了巨大的變化橄唬,Google幾乎每個版本對通知模塊都做了更新升級,可見通知在Android系統(tǒng)中發(fā)揮了舉足輕重的作用蚀狰。在Android N中手销,通知模塊做了如下更新:
- 模板更新:我們正在更新通知模板,新強調(diào)了英雄形象和化身访诱。開發(fā)者將能夠充分利用新模板垫挨,只需進行少量的代碼調(diào)整。
- 消息傳遞樣式自定義:您可以自定義更多與您的使用 MessagingStyle 類的通知相關的用戶界面標簽触菜。您可以配置消息九榔、會話標題和內(nèi)容視圖。
- 捆綁通知:系統(tǒng)可以將消息組合在一起(例如涡相,按消息主題)并顯示組哲泊。用戶可以適當?shù)剡M行拒絕或歸檔等操作。如果您已實現(xiàn) Android Wear 的通知催蝗,那么您已經(jīng)很熟悉此模式切威。
- 直接回復:對于實時通信應用,Android 系統(tǒng)支持內(nèi)聯(lián)回復丙号,以便用戶可以直接在通知界面中快速回復短信先朦。
- 自定義視圖:兩個新的 API 讓您在通知中使用自定義視圖時可以充分利用系統(tǒng)裝飾元素,如通知標題和操作犬缨。
除開第四點直接回復是新功能以外喳魏,其它更新都是UI美觀相關的。本文將會對Android N通知模塊新加的新功能通知直接回復如何使用進行闡述遍尺。闡述這個功能之前截酷,還是先了解一下UI方面的重大變化,整個通知的樣式可以說已經(jīng)發(fā)生了翻天覆地的變化,如下左圖是老版本的通知的樣式迂苛,右圖是N版本的的通知樣式:
同樣的通知在Android M和Android N上顯示有這么大差別三热,Android N中多了一個應用的名稱,這個是非常棒的一個更新三幻,讓用戶能快快速辨別這是哪個APP的通知就漾,對用戶體驗有很大的提升。
長按通知時念搬,左圖是老版本Android M的樣式抑堡,右圖是Android N的樣式:
上圖可見,長按通知時朗徊,Android N提供更加直接快速的通知設置首妖,且現(xiàn)在也可以Block系統(tǒng)級別的應用的通知。對于用戶體驗而言爷恳,這些都是非常棒的細節(jié)更新有缆。
好了,下面就進入正題吧温亲,如果發(fā)一個直接回復的通知棚壁。
創(chuàng)建通知
由于本文是基于Android N的功能開發(fā),所以本文中應用的一些類和方法都是以SDK的API level 24栈虚,如果在實際開發(fā)當中袖外,如果讀者開發(fā)的APP需要在低版本的Android系統(tǒng),讀者需要考慮一下兼容性而不能直接引用本文章中的例子的代碼魂务。如本文中應用Notification.Builder(Android 3.0)曼验,為了兼容低版本,應該使用版本 4 支持庫中的 NotificationCompat.Builder
首先來回顧一下怎樣創(chuàng)建一個普通的通知头镊。創(chuàng)建一個通知蚣驼,有些內(nèi)容是可選的,有些內(nèi)容是不可選的相艇,因此,必需的通知內(nèi)容:
- 小圖標纯陨,由 setSmallIcon() 設置
- 標題坛芽,由 setContentTitle() 設置
- 詳細文本,由 setContentText() 設置
下面就開始吧
創(chuàng)建notification對象
運用notification的建造者模式翼抠,簡單容易地創(chuàng)建notification對象咙轩,如下:
Notification notification = new Notification.Builder(this)
.setSmallIcon(Icon.createWithResource(this.getPackageName(),R.drawable.my_default_icon_label))
.setContentText("You can reply on notification.")
.setContentTitle("Test Notification")
.build();
如上面的代碼,這是一個僅包含了必須內(nèi)容的Notification對象阴颖,由于這些代碼都非常常用了活喊,本文就不再過多的贅述。
添加一個Action
在Android 4.4的版本中量愧,通知的更新升級就增加了Action功能钾菊,所謂Action功能帅矗,就是通知有一個或多個按鈕可以點擊。如下圖:
實現(xiàn)代碼就是調(diào)用addAction()方法煞烫,如下:
Notification notification = new Notification.Builder(this)
.setSmallIcon(Icon.createWithResource(this.getPackageName(), R.drawable.my_default_icon_label))
.setContentText("You can reply on notification.")
.setContentTitle("Test Notification")
.setAutoCancel(true)
.addAction(
new Notification.Action.Builder(
null,
"My Action",
null)
.build())
.build();
添加一個廣播接收Action事件
當點擊通知的Action按鈕浑此,把點擊事件,發(fā)送給一個廣播接收者滞详,代碼如下:
//創(chuàng)建一個啟動廣播的Intent
Intent quickIntent = new Intent();
quickIntent.setAction("quick.reply.input");
//創(chuàng)建Notification對象
Notification notification = new Notification.Builder(this)
.setSmallIcon(Icon.createWithResource(this.getPackageName(), R.drawable.my_default_icon_label))
.setContentText("You can reply on notification.")
.setContentTitle("Test Notification")
.setAutoCancel(true)//點擊通知時自動消失
.addAction(
new Notification.Action.Builder(
null,
"MyAction",
//把Intent轉(zhuǎn)換成PendingIntent
PendingIntent.getBroadcast(this, 1, quickIntent,
PendingIntent.FLAG_ONE_SHOT))
.build())
.build();
//創(chuàng)建廣播接收器
BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
unregisterReceiver(this);
}
};
//注冊廣播接收器
IntentFilter filter = new IntentFilter();
filter.addCategory(this.getPackageName());
filter.addAction("quick.reply.input");
registerReceiver(br, filter);
添加直接回復輸入框
添加直接回復輸入框凛俱,調(diào)用Notification.Action.Builder的addRemoteInput()方法,并創(chuàng)建一個RemoteInput對象作為參數(shù)料饥,RemoteInput.Builder創(chuàng)建對象時傳入?yún)?shù)key蒲犬,該key就是輸入框內(nèi)容的key,在接收內(nèi)容的地方通過key取得內(nèi)容岸啡。如果沒有key也可以取得內(nèi)容原叮,就需要先遍歷所有的數(shù)據(jù),先取得key凰狞,再取得內(nèi)容篇裁。如下:
Notification notification = new Notification.Builder(this)
.setSmallIcon(Icon.createWithResource(this.getPackageName(),R.drawable.my_default_icon_label))
.setContentText("You can reply on notification.")
.setContentTitle("Test Notification")
.setAutoCancel(true)
.addAction(
new Notification.Action.Builder(
null,
"MyAction",
PendingIntent.getBroadcast(this, 1, quickIntent,
PendingIntent.FLAG_ONE_SHOT))
//直接回復輸入框,quick_notification_reply是key
.addRemoteInput(new RemoteInput.Builder("quick_notification_reply")
.setLabel("Please input here!").build())
.build())
.build();
效果如下圖:
把直接回復的內(nèi)容發(fā)送到廣播接收器
在廣播中接收通知輸入框的內(nèi)容赡若,并顯示在APP的TextView上达布,實現(xiàn)如下:
BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle results = RemoteInput.getResultsFromIntent(intent);
if (results != null) {
CharSequence result = results.getCharSequence("quick_notification_reply");
if (TextUtils.isEmpty(result)) {
((TextView) findViewById(R.id.tv)).setText("no content");
} else {
((TextView) findViewById(R.id.tv)).setText(result);
}
}
nm.cancelAll();
unregisterReceiver(this);
}
};
如上面的代碼,通過RemoteInput的getResultsFromIntent()方法逾冬,把Intent中的輸入框內(nèi)容取出來黍聂,然后通過key以方法getCharSequence()取得輸入框輸入的內(nèi)容,把內(nèi)容顯示在TextView上身腻。
效果如下:
結(jié)合Hands Up帶來超棒的用戶體驗
Android更新直接回復通知的功能产还,出于給用戶便捷、快速的操作體驗嘀趟,但是用戶也要下拉通知欄才能進行回復脐区,如果用戶正在使用設備,通過Heands Up就能把直接回復通知這個功能的便捷性淋漓盡致的體現(xiàn)出來她按。
與Hands Up結(jié)合牛隅,只需要在原本的基礎上,設置setFullScreenIntent()即可酌泰,實現(xiàn)如下:
Notification notification = new Notification.Builder(this)
.setSmallIcon(Icon.createWithResource(this.getPackageName(), R.drawable.my_default_icon_label))
.setContentText("You can reply on notification.")
.setContentTitle("Test Notification")
.setAutoCancel(true)
//Hands Up
.setFullScreenIntent(PendingIntent.getActivity(this, 1,
quickIntent,PendingIntent.FLAG_ONE_SHOT), true)
.addAction(
new Notification.Action.Builder(
null,
"MyAction",
PendingIntent.getBroadcast(this, 1, quickIntent,
PendingIntent.FLAG_ONE_SHOT))
//直接回復輸入框
.addRemoteInput(new RemoteInput.Builder("quick_notification_reply").setLabel("Please input here!").build())
.build())
.build();
效果如下:
Hands Up直接回復通知不消失的問題
在Android 7.0的直接回復通知結(jié)合Hands Up一起使用時媒佣,當用戶在輸入框輸入內(nèi)容后,點擊發(fā)送按鈕時陵刹,應用調(diào)用NotificationManager.cancel()方法取消通知默伍,發(fā)現(xiàn)通知還在通知欄,這時需要用戶下拉通知欄,通知才會自動消失也糊。這可能會給用戶帶來不好的用戶體驗炼蹦。這個問題不是issue,是Android本身的設計显设,引用官方一段注釋:
// A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the sending look longer than it takes.
解決這個問題可以通過當用戶在通知輸入完成后框弛,APP成功接收到通知輸入的內(nèi)容后,即APP認為該通知應該消失了捕捂,在調(diào)用NotificationManager.cancel()前瑟枫,先更新通知,把通知的Hands Up特性去除指攒,即去除setFullScreenIntent()慷妙,然后再調(diào)用NotificationManager.cancel()即可。
總結(jié)
本文闡述了Android N中更新的新功能直接回復通知允悦,這個功能給用戶帶來方便膝擂、快速操作的特點,對于即時通訊隙弛、短信等功能非常有用架馋。通過結(jié)合Hands Up通知,能真正發(fā)揮直接回復所帶來的好處全闷,無疑給用戶帶來超棒的使用體驗叉寂。但是,目前快速回復通知只支持text总珠,也就是純文本屏鳍,希望在以后能有更加豐富的類型。