Android直接回复通知

Android直接回复通知

通知直接回复

Android N/7.0

前言

通知(Notification)可为是Android系统中富含特色的一个功能,从Android的第一个版本到Android N,通知这个功能也发生了巨大的变化,Google几乎每个版本对通知模块都做了更新升级,可见通知在Android系统中发挥了举足轻重的作用。在Android N中,通知模块做了如下更新:

  • 模板更新:我们正在更新通知模板,新强调了英雄形象和化身。开发者将能够充分利用新模板,只需进行少量的代码调整。
  • 消息传递样式自定义:您可以自定义更多与您的使用 MessagingStyle 类的通知相关的用户界面标签。您可以配置消息、会话标题和内容视图。
  • 捆绑通知:系统可以将消息组合在一起(例如,按消息主题)并显示组。用户可以适当地进行拒绝或归档等操作。如果您已实现 Android Wear 的通知,那么您已经很熟悉此模式。
  • 直接回复:对于实时通信应用,Android 系统支持内联回复,以便用户可以直接在通知界面中快速回复短信。
  • 自定义视图:两个新的 API 让您在通知中使用自定义视图时可以充分利用系统装饰元素,如通知标题和操作。

除开第四点直接回复是新功能以外,其它更新都是UI美观相关的。本文将会对Android N通知模块新加的新功能通知直接回复如何使用进行阐述。阐述这个功能之前,还是先了解一下UI方面的重大变化,整个通知的样式可以说已经发生了翻天覆地的变化,如下左图是老版本的通知的样式,右图是N版本的的通知样式:

![20170223110950574.png](http://upload-images.jianshu.io/upload_images/7342824-13d301dc73544769.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
20170223110645622.png

同样的通知在Android M和Android N上显示有这么大差别,Android N中多了一个应用的名称,这个是非常棒的一个更新,让用户能快快速辨别这是哪个APP的通知,对用户体验有很大的提升。

长按通知时,左图是老版本Android M的样式,右图是Android N的样式:

20170223110950574.png
20170223111009562.png

上图可见,长按通知时,Android N提供更加直接快速的通知设置,且现在也可以Block系统级别的应用的通知。对于用户体验而言,这些都是非常棒的细节更新。

好了,下面就进入正题吧,如果发一个直接回复的通知。

创建通知

由于本文是基于Android N的功能开发,所以本文中应用的一些类和方法都是以SDK的API level 24,如果在实际开发当中,如果读者开发的APP需要在低版本的Android系统,读者需要考虑一下兼容性而不能直接引用本文章中的例子的代码。如本文中应用Notification.Builder(Android 3.0),为了兼容低版本,应该使用版本 4 支持库中的 NotificationCompat.Builder

首先来回顾一下怎样创建一个普通的通知。创建一个通知,有些内容是可选的,有些内容是不可选的,因此,必需的通知内容:

  • 小图标,由 setSmallIcon() 设置
  • 标题,由 setContentTitle() 设置
  • 详细文本,由 setContentText() 设置

下面就开始吧

创建notification对象

运用notification的建造者模式,简单容易地创建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();

如上面的代码,这是一个仅包含了必须内容的Notification对象,由于这些代码都非常常用了,本文就不再过多的赘述。

添加一个Action

在Android 4.4的版本中,通知的更新升级就增加了Action功能,所谓Action功能,就是通知有一个或多个按钮可以点击。如下图:

20170223111039013.png

实现代码就是调用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按钮,把点击事件,发送给一个广播接收者,代码如下:

//创建一个启动广播的Intent
Intent quickIntent = new Intent();
quickIntent.setAction("quick.reply.input");
//创建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转换成PendingIntent
                    PendingIntent.getBroadcast(this, 1, quickIntent,
                            PendingIntent.FLAG_ONE_SHOT))
                    .build())
    .build();
//创建广播接收器
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);

添加直接回复输入框

添加直接回复输入框,调用Notification.Action.Builder的addRemoteInput()方法,并创建一个RemoteInput对象作为参数,RemoteInput.Builder创建对象时传入参数key,该key就是输入框内容的key,在接收内容的地方通过key取得内容。如果没有key也可以取得内容,就需要先遍历所有的数据,先取得key,再取得内容。如下:

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();

效果如下图:

20170223111140170.png

把直接回复的内容发送到广播接收器

在广播中接收通知输入框的内容,并显示在APP的TextView上,实现如下:

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中的输入框内容取出来,然后通过key以方法getCharSequence()取得输入框输入的内容,把内容显示在TextView上。

效果如下:

结合Hands Up带来超棒的用户体验

Android更新直接回复通知的功能,出于给用户便捷、快速的操作体验,但是用户也要下拉通知栏才能进行回复,如果用户正在使用设备,通过Heands Up就能把直接回复通知这个功能的便捷性淋漓尽致的体现出来。

与Hands Up结合,只需要在原本的基础上,设置setFullScreenIntent()即可,实现如下:

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();

效果如下:

20170223111559596.gif

Hands Up直接回复通知不消失的问题

在Android 7.0的直接回复通知结合Hands Up一起使用时,当用户在输入框输入内容后,点击发送按钮时,应用调用NotificationManager.cancel()方法取消通知,发现通知还在通知栏,这时需要用户下拉通知栏,通知才会自动消失。这可能会给用户带来不好的用户体验。这个问题不是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成功接收到通知输入的内容后,即APP认为该通知应该消失了,在调用NotificationManager.cancel()前,先更新通知,把通知的Hands Up特性去除,即去除setFullScreenIntent(),然后再调用NotificationManager.cancel()即可。

总结

本文阐述了Android N中更新的新功能直接回复通知,这个功能给用户带来方便、快速操作的特点,对于即时通讯、短信等功能非常有用。通过结合Hands Up通知,能真正发挥直接回复所带来的好处,无疑给用户带来超棒的使用体验。但是,目前快速回复通知只支持text,也就是纯文本,希望在以后能有更加丰富的类型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容