android7:通知直接回复
第一步, 我们需要创建一个RemoteInput
第二步, 创建一个PendingIntent, 这个PendingIntent指当我们点击”发送”的时候调用什么
第三步, 创建一个直接回复的Action
第四步, 创建notification
第五步, 发送通知
一共5个步骤我们就可以创建一个带有”直接回复”功能的通知了, 而且这5步里2,4,5应该是我们熟悉的代码, 下面我们就来一步步的完成代码.
首先, 创建RemoteInput
RemoteInput remoteInput =newRemoteInput.Builder(RESULT_KEY) .setLabel("回复这条消息") .build();
1
2
3
1
2
3
很简单的一个builder, 首先Builder的构造我们需要一个String类型的key, 这个key是干嘛用的? 其实就是我们方便在处理回复的时候拿内容的. 其次一个setLabel方法, 可以对照着上面的图来看看这是哪一部分的内容, 说白了, 这其实就是一个EditText的Hint值.
接下来继续第二步, 创建一个PendingIntent, 这个PendingIntent在这里的作用是启动一个service,所以代码是这样的:
Intent intent =newIntent(this, SendMsgService.class);PendingIntent pi = PendingIntent.getService(this,1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
1
2
1
2
都是大家熟悉的代码, 我们接着来看第三步, 创建一个直接回复的Action
NotificationCompat.Action act =newNotificationCompat.Action.Builder(R.mipmap.ic_launcher,"回复", pi) .addRemoteInput(remoteInput).build();
1
2
1
2
又是一个Builder, 这个Builder的构造中有三个参数, 第一个参数是一个logo, 搞过通知的朋友肯定对通知的logo都很熟悉了, 第二个参数是这个Action的标签, 对应上面demo中我们要点击的那个按钮, 第三个参数是当我们点击”回复”的时候要干嘛. 接下来一个addRemoteInput方法将上面我们创建的RemoteInput传递进来.
第四步, 创建一个notification, 这个过程中大家都知道也是一个builder, 不过这个builder中肯定有我们不熟悉的方法, 要们上面的Action怎么设置呢?
NotificationCompat.Builder builder =newNotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("请问是否需要信用卡?") .setContentText("您好,我是XX银行的XX经理, 请问你需要办理信用卡吗?") .setColor(Color.CYAN) .addAction(act) .setCategory(Notification.CATEGORY_MESSAGE);
1
2
3
4
5
6
7
1
2
3
4
5
6
7
从上往下一个个的来, 略…略…略…,setColor方法的作用是设置一个accent颜色, 对应上面的demo就是那个”回复”和点击”回复”后输入框的背景颜色.addAction方法就是将我们上面创建的Action设置进来,setCategory是指定通知的类型, 这里我们指定为消息类型.
最后一步, 发送通知
NotificationManager nm = getSystemService(NotificationManager.class);
nm.notify(NOTIFICATION_ID, builder.build());
1
2
1
2
没撒好说的, 就这样简单的几步, 一个具有”直接回复”功能的通知就发出来了, 不过还没完, 虽然通知出来了, 但是用户回复的内容我们还没处理. 这些逻辑的处理我们放到上面提到的那个service里执行.
那这个处理流程是怎样的呢? 还是先来罗列下流程.
拿到用户输入的内容
模拟发送的延迟
模拟发送成功, 取消通知
再次一步步的跟代码, 首先我们要拿到用户输入的内容, 我们可以通过RemoteInput的一个静态方法getResultsFromIntent直接拿到一个Bundle, 然后我们就可以根据上面构建RemoteInput的时候使用的key来拿到内容了.
Bundle replyBundle = RemoteInput.getResultsFromIntent(intent);if(replyBundle !=null) {// 根据key拿到回复的内容String reply = replyBundle.getString(MainActivity.RESULT_KEY); reply(reply);}
1
2
3
4
5
6
1
2
3
4
5
6
拿到内容后, 我们就来模拟回复了, 这个操作是在reply方法中完成的.
privatevoidreply(finalString reply) { mHandler.postDelayed(newRunnable() {@Overridepublicvoidrun() { Log.d("reply","reply: "+ reply); onReply(); } },1000);}}
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
这里我们延迟1000ms后表示回复成功, 然后调用onReply方法.
privatevoidonReply() {finalNotificationManager nm = getSystemService(NotificationManager.class); mHandler.post(newRunnable() {@Overridepublicvoidrun() {// 更新通知为“回复成功”Notification notification =newNotificationCompat.Builder(SendMsgService.this) .setSmallIcon(R.mipmap.ic_launcher) .setContentText("回复成功") .build(); nm.notify(MainActivity.NOTIFICATION_ID, notification); } });// 最后将通知取消mHandler.postDelayed(newRunnable() {@Overridepublicvoidrun() { nm.cancel(MainActivity.NOTIFICATION_ID); } },2000);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
在onReply里我们就来干剩下的事了, 包括发送一个”发送成功”的消息,然后延迟取消通知.
代码很简单, 主要的是创建直接回复的通知和如何拿到用户输入的内容, 如果大家的APP中有这样的需求, 可以考虑在适配Android7的时候加入直接回复的功能.