文档章节

Android N在通知栏上实现直接回复消息

shenhuniurou
 shenhuniurou
发布于 2017/07/05 22:54
字数 947
阅读 120
收藏 1

Android N 版本中的通知又做了进一步的改进。主要改进了如下几点:

  • 新的 UI 效果
  • 增强对自定义 View 的支持
  • 支持通知内直接回复
  • 新的 MessagingStyle 样式通知
  • 聚合通知 同一类型通知可以聚合一起了,再也不用担心用户手机满屏都是通知了

刚好,我司的app是一款社交类型的app,为了适配Android N的这些特性,于是花了点时间给自己的app加上了通知栏直接回复的功能。直接上代码:

public static void sendNotification(Context context, String tickerText, String title, String content, Intent intent, String user, int notifyId) {

    // 初始化NotificationManager
    NotificationManager messageNotificatioManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    
    // 创建通知
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
    builder.setTicker(content);
    builder.setContentInfo(tickerText);
    builder.setContentText(content);
    builder.setContentTitle(title);
    builder.setSmallIcon(R.drawable.icon_push);
    builder.setAutoCancel(true);

    // 设置通知的优先级(悬浮通知)
    builder.setPriority(NotificationCompat.PRIORITY_MAX);
    
    // 根据用户的偏好设置通知是否有声音和震动
    boolean hasVoice = AppDataCache.getInstance().getIsVoice();
    boolean hasVibrate = AppDataCache.getInstance().getIsShake();
    if (hasVoice) {
        // 使用系统通知声音
        Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        // 设置通知的提示音
        builder.setSound(alarmSound);
    }
    if (hasVibrate) {
        long [] pattern = { 70, 150, 70, 150 };
        // 设置通知的震动
        builder.setVibrate(pattern);
    }

    builder.setWhen(System.currentTimeMillis());
    pendIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(pendIntent);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        adaptAndroidN(context, builder, user);
    }

    messageNotification = builder.build();
    messageNotification.flags = Notification.FLAG_AUTO_CANCEL;
    messageNotificatioManager.notify(notifyId, messageNotification);
}

另外像微信QQ,用户在设置通知是否有声音时,点击选中时会播放一遍系统通知声音,具体做法是这样的:

// 播放系统通知铃声
public static void palySound(Context context) {
    Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    MediaPlayer mMediaPlayer = MediaPlayer.create(context, soundUri);
    mMediaPlayer.setLooping(false);
    mMediaPlayer.start();
}

其中RingtoneManager.TYPE_NOTIFICATION的值有如下几种:

public static final int TYPE_RINGTONE = 1;
public static final int TYPE_NOTIFICATION = 2;
public static final int TYPE_ALARM = 4;
public static final int TYPE_ALL = TYPE_RINGTONE | TYPE_NOTIFICATION | TYPE_ALARM;

也就是通知声音、铃声声音、闹钟声音和这三种的组合。

在Android N上通知要显示时间,必须要设置下面这句才可以

builder.setShowWhen(true);

上面发送通知的方法中,直接在通知栏中回复的关键代码就是

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    adaptAndroidN(context, builder, user);
}
private static void adaptAndroidN(Context context, NotificationCompat.Builder builder, String user) {
    builder.setShowWhen(true);
    String replyLabel = "回复";
    RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
        .setLabel(replyLabel)
        .build();
    Intent intent = new Intent(context, ReplyService.class);
    intent.putExtra("userId", user);
    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.icon_push, replyLabel, pendingIntent)
            .addRemoteInput(remoteInput)
            .setAllowGeneratedReplies(true)
            .build();
    builder.addAction(action);
}

这里我只添加了一个回复按钮,是可以添加多个的,看源码发现addAction其实是把这个action添加到一个ArrayList中的,所有肯定是可以显示多个按钮的。

回复输入内容后,点击右边的发送按钮,这个后续动作需要我们通过PendingIntent来实现,比如我这里是要将这条消息发送给对方,所以我使用了IntentService来完成。

public class ReplyService extends IntentService implements SendMessageCallback {

    private static final String KEY_TEXT_REPLY = "key_text_reply";
    private DatabaseHelper helper;
    private SocketMessage tmpMsg;
    private String userId;

    public ReplyService() {
        super("ReplyService");
    }


    @Override protected void onHandleIntent(@Nullable Intent intent) {
        Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
        String message = null;
        if (remoteInput != null) {
            message = remoteInput.getCharSequence(KEY_TEXT_REPLY).toString();
        }

        //TODO:发送消息message
    }

}

关键点就是在onHandleIntent方法中通过RemoteInput获取到刚输入的信息:

Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
String message = null;
if (remoteInput != null) {
    message = remoteInput.getCharSequence(KEY_TEXT_REPLY).toString();
}

执行完一系列操作后,IntentService自动结束,完成。

结尾处关于通知我有一点疑惑,就是在Android5.0之后的系统,像QQ微信是刚下载安装后它就有悬浮锁屏显示通知的权限,而普通的app是没有的,即使我将优先级设置为PRIORITY_MAX还是不行。不知道是不是国内的手机厂商将QQ微信加入白名单了啊?如果让用户手动去设置这招怕是不行,因为并不是每个用户都像Android开发者一样爱去折腾手机。我目前是用Android7.1的原生系统测试的,是默认可以显示悬浮通知的。

参考文章 Android Nougat 的通知改进

© 著作权归作者所有

共有 人打赏支持
shenhuniurou
粉丝 19
博文 78
码字总数 63826
作品 0
广州
Android工程师
Android 7.0 新特性

Android7.0提供新功能以提升性能、生产效率和安全性。 关于Android N的性能改进,Android N建立了先进的图形处理Vulkan系统,能少的减少对CPU的占用。与此同时,Android N加入了JIT编译器,安...

安卓笔记侠
08/09
0
0
Android通知栏微技巧,8.0系统中通知栏的适配

转载请注明出处:https://blog.csdn.net/guolinblog/article/details/79854070 大家好,今天我们继续来学习Android 8.0系统的适配。 之前我们已经讲到了,Android 8.0系统最主要需要进行适配...

sinyu890807
04/17
0
0
android Notification 的使用(转自他人)

最近一直在研究 android ,并一边研究一边做应用。其中遇到了把程序通知常驻在 Notification 栏,并且不能被 clear 掉(就像android QQ一样)的问题。经过研究实现了其功能,现把 Notificati...

eric_zhang
2012/02/10
0
0
通过PhoneGap在Android上去推送通知

需求 必备知识 这篇文章至少需要有过一个中等层次的PhoneGap的开发经验 必须产品 PhoneGap Build 用户级 全部适用 我上一篇文章是通过PhoneGap能够在苹果设备上推送通知。在这篇文章中,我将...

james_laughing
2014/12/18
0
0
Android Notification 通知学习详细笔记

通知栏通知在Android APP中的使用极为频繁,比如短信通知,QQ,微信消息通知,App 更新进度转态显示,截图时后图片进行删除或分享,查看操作等等。本篇文章记录了如何使用 Notification 显示...

denua_
09/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

20180920 rzsz传输文件、用户和用户组相关配置文件与管理

利用rz、sz实现Linux与Windows互传文件 [root@centos01 ~]# yum install -y lrzsz # 安装工具sz test.txt # 弹出对话框,传递到选择的路径下rz # 回车后,会从对话框中选择对应的文件传递...

野雪球
今天
2
0
OSChina 周四乱弹 —— 毒蛇当辣条

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 达尔文:分享花澤香菜/前野智昭/小野大輔/井上喜久子的单曲《ミッション! 健?康?第?イチ》 《ミッション! 健?康?第?イチ》- 花澤香菜/前野智...

小小编辑
今天
8
3
java -jar运行内存设置

java -Xms64m #JVM启动时的初始堆大小 -Xmx128m #最大堆大小 -Xmn64m #年轻代的大小,其余的空间是老年代 -XX:MaxMetaspaceSize=128m # -XX:CompressedClassSpaceSize=6...

李玉长
今天
4
0
Spring | 手把手教你SSM最优雅的整合方式

HEY 本节主要内容为:基于Spring从0到1搭建一个web工程,适合初学者,Java初级开发者。欢迎与我交流。 MODULE 新建一个Maven工程。 不论你是什么工具,选这个就可以了,然后next,直至finis...

冯文议
今天
2
0
RxJS的另外四种实现方式(四)——性能最高的库(续)

接上一篇RxJS的另外四种实现方式(三)——性能最高的库 上一篇文章我展示了这个最高性能库的实现方法。下面我介绍一下这个性能提升的秘密。 首先,为了弄清楚Most库究竟为何如此快,我必须借...

一个灰
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部