Android Notifications 百发百中之第二发

Android Notifications 百发百中之第一发

第一发主要介绍了 Notifications 中如果创建一个标准通知,如何设置通知的点击事件,通知的基本操作,如何为通知添加 Action 以及通知的启动和取消。

第二发主要介绍通知栏的各种样式以及如何设置样式来创建你所需要的通知栏,依然是这个表格:
样式 描述
Normal 标准通知,显示标题和单行内容
BigText 多行文字,显示标题和多行内容
BigPicture 显示文字和图片,显示标题、内容和图片
Inbox 邮件,显示标题和多行邮件内容
Messaging 消息,显示和朋友的对话内容
Media 音乐播放器,显示常驻通知栏,可以执行各种操作
Custom 自定义,自定义 layout 的通知栏

在标准通知中,一般情况下通知的标题和内容都只能显示一行,通知内容比较固定,有些时候,一行根本就写不了什么东西,如果想看详情就不得不打开 app,当时就想如果直接在通知上能看到更多的东西该多好啊,然后福利就来了。 Google 你懂的,作为一个世界著名但在中国不存在的公司还是很贴心的,从 Android 4.1 开始,Google 为通知定义好了各种各样的样式,这样你就不需要去自定义,直接使用样式就可以了,这些样式可以满足我们大部分的需求。所以作为一个 Android 开发者那可真是痛并快乐着。怎么痛?呵呵,做过的都知道。

BigText

如上图所示,你可以点击通知上的向下和向上的箭头来展开和收缩多行文字,比如新闻类的 app,你可以设置多行文字显示给用户更多的内容。


String title = "This is big text title";
String text = "A notification is a message you can display " +
              "to the user outside of your application's normal UI. " +
              "When you tell the system to issue a notification, " +
              "it first appears as an icon in the notification area. ";
NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
style.setBigContentTitle(title);
style.bigText(text);
style.setSummaryText(context.getString(R.string.app_name));

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setLargeIcon(largeIcon)
       .setSmallIcon(R.drawable.cry)
       .setTicker(context.getString(R.string.app_name))
       .setWhen(System.currentTimeMillis())
       .setContentTitle(title)
       .setContentText(text)
       .setStyle(style)
       .setCategory(NotificationCompat.CATEGORY_MESSAGE)
       .setAutoCancel(isAutoCancel)
       .setContentIntent(pendingIntent);

如上代码所示,BigText 通知的创建和标准通知的创建的唯一区别就在于设置样式。

style.setSummaryText(),设置应用名称,跟 builder.setTicker() 保持一致即可,当然你也可以设置成其它名称;
style.setBigContentTitle(),设置标题,跟 builder.setContentTitle() 保持一致即可,这样能保证展开和收缩的标题是一样的;
style.bigText(),设置内容,跟 builder.setContentText() 保持一致即可,如果设置的不一样,则在展开和收缩的时候,显示的内容会有变化,会显得比较突兀。

使用 builder.setStyle() 设置样式之后,我们就可以愉快的显示很多内容了。

注意标准通知中的所有属性和操作均可以在 BigText 中使用,比如点击事件和增加 Action 等。

BigPicture

如上图所示,你可以点击通知上的向下和向上的箭头来展开和收缩图片,比如购物类的 app,在推送商品的同时可以推送此商品的图片,让人有感觉的图片可以分分钟增加用户购物的欲望。

String title = "This is big picture title";
String text = "This is big picture message";

NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
style.bigPicture(BitmapFactory.decodeResource(context.getResources(), R.drawable.google));
style.setBigContentTitle(title);
style.setSummaryText(text);

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setLargeIcon(largeIcon)
       .setSmallIcon(R.drawable.cry)
       .setTicker(context.getString(R.string.app_name))
       .setWhen(System.currentTimeMillis())
       .setContentTitle(title)
       .setContentText(text)
       .setStyle(style)
       .setCategory(NotificationCompat.CATEGORY_MESSAGE)
       .setAutoCancel(isAutoCancel)
       .setContentIntent(pendingIntent);

如上代码所示,BigPicture 通知的创建和标准通知的创建的唯一区别就在于设置样式。

style.setSummaryText(),设置应用名称,跟 builder.setTicker() 保持一致即可,当然你也可以设置成其它名称;
style.setBigContentTitle(),设置标题,跟 builder.setContentTitle() 保持一致即可,这样能保证展开和收缩的标题是一样的;
style.bigPicture(),设置图片内容, builder 里面是无法直接设置图片的。

使用 builder.setStyle() 设置样式之后,我们就可以愉快的显示图片了。

注意标准通知中的所有属性和操作均可以在 BigPicture 中使用,比如点击事件和增加 Action 等。

Inbox

顾名思义,收件箱,主要用来推送多个邮件。如上图所示,你可以点击通知上的向下和向上的箭头来展开和收缩多个邮件。

NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
style.addLine("This is first inbox message");
style.addLine("This is second inbox message");
style.addLine("This is third inbox message");
style.addLine("This is fourth inbox message");
style.addLine("This is fifth inbox message");
style.addLine("This is sixth inbox message");
style.addLine("This is seventh inbox message");
style.setBigContentTitle("This is inbox title");
style.setSummaryText(context.getString(R.string.app_name));
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setLargeIcon(largeIcon)
       .setSmallIcon(R.drawable.cry)
       .setTicker(context.getString(R.string.app_name))
       .setWhen(System.currentTimeMillis())
       .setContentTitle("This is inbox title")
       .setContentText("This is inbox message")
       .setCategory(NotificationCompat.CATEGORY_EMAIL)
       .setStyle(style)
       .setAutoCancel(isAutoCancel)
       .setContentIntent(pendingIntent);

如上代码所示,Inbox 通知的创建和标准通知的创建的唯一区别就在于设置样式。

style.setSummaryText(),设置应用名称,跟 builder.setTicker() 保持一致即可,当然你也可以设置成其它名称;
style.setBigContentTitle(),设置标题,跟 builder.setContentTitle() 保持一致即可,这样能保证展开和收缩的标题是一样的;
style.addLine(),设置 Inbox 的邮件内容。

使用 builder.setStyle() 设置样式之后,我们就可以愉快的显示多封邮件了。

注意标准通知中的所有属性和操作均可以在 Inbox 中使用,比如点击事件和增加 Action 等。

Messaging

如上图所示,Messaging 样式主要用来做群组聊天,比如微信群,不用打开 app 就可以看到群里所有人的聊天,还可以直接回复。你可以点击通知上的向下和向上的箭头来展开和收缩群组聊天。

List<Message> list = new ArrayList<>();
list.add(new Message("What do you plan to do on the weekend?"
                    , System.currentTimeMillis(), "Smile"));
list.add(new Message("Sleep.", System.currentTimeMillis(), "Tracy"));
list.add(new Message("Go to Beijing..", System.currentTimeMillis(), "SB"));
list.add(new Message("Play football", System.currentTimeMillis(), "Naocan"));
list.add(new Message("Coding...", System.currentTimeMillis(), "Developer"));

String title = "This is messaging title";
String text = "This is messaging message";

NotificationCompat.MessagingStyle style = new NotificationCompat.MessagingStyle("Smile");

for (Message message : list) {
    style.addMessage(message.getText(), message.getTime(), message.getSender());
}
style.setConversationTitle(title);

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setLargeIcon(largeIcon)
       .setSmallIcon(R.drawable.cry)
       .setTicker(context.getString(R.string.app_name))
       .setWhen(System.currentTimeMillis())
       .setContentTitle(title)
       .setContentText(text)
       .setCategory(NotificationCompat.CATEGORY_MESSAGE)
       .setStyle(style)
       .setAutoCancel(isAutoCancel)
       .setContentIntent(pendingIntent);

如上代码所示,Messaging 通知的创建和标准通知的创建的唯一区别就在于设置样式。

style.setConversationTitle(),设置会话标题,比如群组名称,跟 builder.setContentTitle() 保持一致即可,当然你也可以设置成其它名称;
style.addMessage(),设置每个人的聊天内容。

使用 builder.setStyle() 设置样式之后,我们就可以愉快的显示多人聊天内容了。

注意标准通知中的所有属性和操作均可以在 Messaging 中使用,比如点击事件和增加 Action 等。

增加群组聊天直接回复 Action:

RemoteInput input = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel("reply").build();

Intent reply = new Intent();
reply.setAction(REPLY_MESSAGING);
reply.setClass(context, NotificationReceiver.class);
PendingIntent pendingReply = PendingIntent.getBroadcast(context
                            , (int) SystemClock.uptimeMillis()
                            , reply
                            , PendingIntent.FLAG_UPDATE_CURRENT);


NotificationCompat.Action action = new NotificationCompat.Action
                .Builder(0, "reply", pendingReply)
                .addRemoteInput(input)
                .setAllowGeneratedReplies(true)
                .build();

builder.addAction(action);

在广播中接收发送的内容,然后通知通知栏更新群组聊天内容。

Media

如上图所示,Media 主要用来关联音频播放服务的,通知栏点击后不会自动消失,通知栏的清空也不可用,但你可以左滑或右滑删除,所以一般要设置 setOngoing(true) 防止删除。你还可以在通知栏快捷的暂停、继续、切换歌曲等等,同样的你可以点击通知上的向下和向上的箭头来展开和收缩更多内容。

String title = "This is media title";
String text = "This is media message";
style.setShowCancelButton(true);
style.setCancelButtonIntent(pendingIntent);
style.setShowActionsInCompactView(0, 1);

style.setMediaSession(new MediaSessionCompat(context, "MediaSession",
        new ComponentName(context, Intent.ACTION_MEDIA_BUTTON), null).getSessionToken());

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setLargeIcon(largeIcon)
       .setSmallIcon(R.drawable.cry)
       .setTicker(context.getString(R.string.app_name))
       .setWhen(System.currentTimeMillis())
       .setContentTitle(title)
       .setContentText(text)
       .setCategory(NotificationCompat.CATEGORY_TRANSPORT)
       .setStyle(style)
       .setOngoing(true)
       .setContentIntent(pendingIntent);

Intent back = new Intent();
back.setAction(BACK);
back.setClass(context, NotificationReceiver.class);
PendingIntent pendingBack = PendingIntent.getBroadcast(context
                                , (int) SystemClock.uptimeMillis()
                                , back, PendingIntent.FLAG_UPDATE_CURRENT);

Intent next = new Intent();
next.setAction(NEXT);
next.setClass(context, NotificationReceiver.class);
PendingIntent pendingNext = PendingIntent.getBroadcast(context
                            , (int) SystemClock.uptimeMillis()
                            , next, PendingIntent.FLAG_UPDATE_CURRENT);

Intent pause = new Intent();
pause.setAction(PAUSE);
pause.setClass(context, NotificationReceiver.class);
PendingIntent pendingPause = PendingIntent.getBroadcast(context
                           , (int) SystemClock.uptimeMillis()
                           , pause, PendingIntent.FLAG_UPDATE_CURRENT);

builder.addAction(R.drawable.back, "", pendingBack);
builder.addAction(R.drawable.pause, "", pendingPause);
builder.addAction(R.drawable.next, "", pendingNext);

如上代码所示,Media 通知的创建和标准通知的创建的唯一区别就在于设置样式。

style.setShowCancelButton(true),设置是否显示一个关闭此通知的关闭按钮,在 Adnroid 5.0 之前设置为 true 才会显示,在 5.0 及以上,不管设置为 true 还是 false 均不会显示,也就是说 5.0 及以上没有这个功能,需要通过自定义通知去实现关闭;
style.setCancelButtonIntent(),设置关闭按钮的点击事件;
style.setShowActionsInCompactView(0, 1),设置通知栏收缩时显示的按钮,显示按钮的顺序是通知栏展开时的从左到右,0代表只显示第一个,(0, 1)代表显示第一个和第二个。

使用 builder.setStyle() 设置样式之后,我们就可以愉快的显示音乐播放器了。

注意为了保证音乐能够持续的播放,你需要在 Service 中创建 Media 样式的通知栏,通过 startForeground 启动通知栏,使得通知栏能够在前台显示,避免被销毁。

详细的代码请参见GitHub

推荐阅读:
1、Android 全局管理 Activity 栈
2、Android Notifications 百发百中之第一发
敬请期待 Android Notifications 百发百中之第三发(自定义通知)

Smile Wei wechat
请扫码关注我的微信公众号