小米手机 MIUI 10 通知样式及能力适配说明

小米手机 MIUI 10 通知样式及能力适配说明

MIUI 10 通知栏基于 Android O 做了重构,大大增强了通知栏的能力,分别是:

  • 支持 6 种通知样式
  • 支持 Large icon
  • 支持 Actions
  • 支持快捷回复 (Direct reply) 

1. 前言

  • 以下图片,仅用于示意,线上效果可能会有变化,请在最新 MIUI 版本中测试样式及逻辑。
  • 以下图片示例的都是 MIUI 10 国内版的效果,国际版的布局将会沿用原生 Android 的样式。
  • 以下特性,全部需要开发者自行适配。通知栏只是提供基础能力, 但是否使用由开发者决定。
  • 以下提及的接口均为 Android 标准接口,可在官方文档中查询,但也要注意是从哪个 Android 版本开始支持。
  • 对于使用推送通道的开发者,需要确认相关推送通道是否支持以下能力及相关标准接口,若不支持,则无法使用相关能力。

2. 六种通知样式 (template)

原生 Android O 支持6种通知样式(或称 template),MIUI 10 也将完全兼容这些样式。

(关于原生 Android O 的通知样式介绍,详见 https://material.io/design/platform-guidance/android-notifications.html#templates )

2.1. 标准样式 (Standard template)

标准样式是最常见的样式,也是通知栏的默认样式,有以下特点:

  • 一般包含“标题”、“内容”、“图标”、“时间戳”4个元素
  • 一般无大视图

2.2. 大文本样式 (Big text template)

自 API 16 (Android 4.1) 引入,用以展示更多的文本内容,有以下特点:

  • 有标准视图 (standard view),看起来与标准样式 (Standard template) 一样。
  • 有大视图 (expanded view),有更大的面积,允许展示更多的内容。
  • 通过长按通知来切换标准视图和大视图。

代码示例:

Notification notif = new Notification.Builder(mContext)
   .setContentTitle("特斯拉召回两千余辆 ModelX")
   .setContentText("本次召回范围仅限部分车辆")
   .setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
   .setColor(ContextCompat.getColor(context, R.color.primary_light))
   .setPriority(Notification.PRIORITY_MAX)
   .setVibrate(new long[0])
   .setStyle(new Notification.BigTextStyle()
       .bigText("据上周美联社信息报道,特斯拉已宣布计划在全球范围内召回大约1.1万辆ModelXSUV,原因是后座可能无法锁定。"))
   .build();

该样式还有更多的接口供开发者使用,详见官方文档 https://developer.android.com/reference/android/app/Notification.BigTextStyle。

2.3. 大图样式 (Big picture template)

自 API 16 (Android 4.1) 引入,用以在通知里展示大图,适用于富媒体的内容:

  • 有标准视图 (standard view),看起来与标准样式 (Standard template) 一样。
  • 有大视图 (expanded view),支持展示一张大图,但无法与Big text template 共用,即无法展示长文本。
  • 通过长按通知来切换标准视图和大视图。

代码示例:

Notification notif = new Notification.Builder(mContext)
    .setContentTitle("Unsplash Curation")
    .setContentText("The best new high-res photos from Unsplash. Here’s a few of our team’s favourites from today.")
    .setSmallIcon(R.drawable.new_post)
    .setStyle(new Notification.BigPictureStyle()
        .bigPicture(aBigBitmap))
    .build();

更多的接口详见官方文档 https://developer.android.com/reference/android/app/Notification.BigPictureStyle

2.4. 进度条样式 (Progress template)

自 API 14 (Android 4.0) 引入,有以下特点:

  • 类型1:“无明确进度 (indeterminate)”,即无法预估结束时间,类似于 loading 动画。
  • 类型2:“有明确进度 (determinate)”,可以预估结束时间。
  • 支持标准视图 (standard view),类似标准样式加上了进度条。
  • 支持大视图 (expanded view),一般是展示按钮,如「取消」。
  • 进度条样式可以和 Big text、Big picture 混用(留待各位尝试)

代码示例:

代码层面上,Progress template 并不是一种 Style,无法通过 setStyle 来设置,而是通过 setProgress 来配置,因此才可以和 Big text、Big picture 混用。

以下是两种进度类型的代码示例:

#类型1:indeterminate
Notification notif = new Notification.Builder(mContext)
    .setContentTitle("正在下载安装包")
    .setContentText("即将更新至 MIUI 10")
    .setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
    .setProgress(100,50,true)
    .addAction(cancelAction)
    .build();
#类型2:determinate
Notification notif = new Notification.Builder(mContext)
    .setContentTitle("正在下载安装包")
    .setContentText("下载进度35%")
    .setSubText("还有27分钟")
    .setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
    .setProgress(100,35,false)
    .addAction(cancelAction)
    .build();

更详细的实现说明,也可以看官方文档 https://developer.android.com/training/notify-user/build-notification#progressbar。

2.5. 媒体样式 (Media template)

自 API 21 (Android 5.0) 引入,为音乐、广播等媒体播放设计的通知样式,详细介绍见这个文档 https://dev.mi.com/console/doc/detail?pId=1300 。

2.6. 对话样式 (Messaging template)

自 API 24 (Android 7.0) 引入,为对话式内容设计的通知样式,适用于 IM / 邮件等涉及会话的应用。有以下特点:

  • 支持单聊和群聊两种会话模式。
  • 支持普通视图 (standard view),类似标准样式。
  • 支持大视图 (expanded view),支持显示会话的上下文。

代码示例:

#类型1:单聊
Notification notif = new Notification.Builder()
    .setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
    .setLargeIcon(userAvatar)
    .setStyle(new MessagingStyle("我")
            .addMessage("爱乐之城怎么样", 1, "我")
            .addMessage("很不错啊,金球奖得主呢", 2, "韩梅梅")
            .addMessage("什么时候上映的?最近老在别的地方看到这个电影的介绍,被吊起胃口了", 3, "我")
            .addMessage("中国要情人节才上映", 4, "韩梅梅"))
    .addAction(replyAction)
    .build();
#类型2:群聊
Notification notif = new Notification.Builder()
    .setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
    .setLargeIcon(groupAvatar)
    .setStyle(new MessagingStyle("我")
        .setConversationTitle("这里是群聊名称")
        .addMessage("威少3节41分也是666", 1, "winson")
        .addMessage("落后好多咧", 2, "超")
        .addMessage("其他的不给力", 3, "winson")
        .addMessage("勇士赢是正常,但这不是一场普通的比赛了,大家都打出火气来了", 4, "我"))
    .addAction(replyAction)
    .build();

更多的接口详见官方文档 https://developer.android.com/reference/android/app/Notification.MessagingStyle

上面的例子,大家应该注意到 setLargeIcon 和 addAction 这两个方法,这是用来显示「用户头像」和「回复」按钮的方法。但这两个方法,不限于 Messaging template,可用于所有通知样式中,下面将仔细说明。

3. 支持 Large icon(测试性功能)

Android 通知默认没有 large icon,但开发者可以通过 setLargeIcon 方法 (自 API 11 – Android 3.0 引入) 给通知增加 large icon,丰富通知的内容,尤其适用于 IM / 邮件等场景。

自 MIUI 10 开始,MIUI 通知栏正式支持显示 large icon,示例效果如下。

代码示例:

Notification notif = new Notification.Builder()
    .setContentTitle("韩梅梅")
    .setContentText("中国要情人节才上映")
    .setSmallIcon(R.drawable.ic_chat_black_24dp)
    .setLargeIcon(userAvatar)
    .build();

未设置large icon时,会默认用应用桌面图标代替。有几点值得说明:

  • setLargeIcon 方法适用于所有通知样式,不限于上述例子。开发者可以配合 setStyle 方法,灵活搭配不同的样式。
  • MIUI 系统会自动在 large icon 的右下角添加应用 icon,以标示该通知的来源。因此不要把 large icon 设置为应用图标。
  • 请不要滥用 large icon,我们后续会视情况而定是否收紧这个能力。

4. 支持 Actions

Actions 指的是通知的快捷按钮,该特性自 API 16 (Android 4.1) 引入,并在 API 20 (Android 4.4W) 中更新。

在 MIUI 10,Actions 的样式如下(除媒体通知外,最多可以设置3个 Actions)。

有几点值得说明:

  • 默认不会有 Actions,需要开发者通过 addAction 主动声明。
  • 任何通知样式都可以添加 Actions(效果如下图),开发者可以自由搭配
  • Actions 只能在大视图时显示,在 MIUI 10,除了媒体通知,所有通知默认展示标准视图(标准视图不显示 Actions )。

5. 支持快捷回复 (Direct reply)

快捷回复 (Direct reply) 是 Android 7.0 引入的新功能,开发者适配后,可以支持在通知栏直接回复消息,而不用调起应用,示意图如下:

Direct reply 也不限通知样式(效果如下图),开发者可与不同的通知样式组合搭配。但 Direct reply 依赖于 Actions,因此需要先显示 Actions,才能触发 Direct reply。

关于 Direct reply 的实现方式,可以参考以下资料:

6. FAQ

6.1. 如何判断 MIUI 版本

有以下方法:

android.os.SystemProperties.get("ro.miui.ui.version.code", "7");// 如果返回值是「8」,就是 MIUI 10

android.os.SystemProperties.get("ro.miui.ui.version.name", "");// 如果返回值是「V10」,就是 MIUI 10

6.2. 如何测试

升级到  MIUI 10 最新开发版即可,支持的机型和下载链接如下:

小米MIUI 10 通知类别 (Channel) 适配说明

小米MIUI 10 通知类别 (Channel) 适配说明

1. 什么是通知类别 / Channel

通知类别 (channel) 是 Android O 引入的新功能,旨在解决以下问题:

  • 应用的通知越来越多,给用户造成明显打扰。
  • 但用户只能全局屏蔽这个应用的全部通知,不能屏蔽部分,然后留下对自己有用的。

为了解决这个问题,Android 要求开发者给自己的通知分成若干类,然后允许用户单独屏蔽这个类别的通知。以爱奇艺(v9.5.0) 为例,将通知分成了 4 种 Channel,3 个 Channel Group,如下图:

简单解释一下:

  • Channel:实际的通知类别,爱奇艺分成了4类通知。
  • Channel Group:一组 channel,仅用于做分组区分,没有更多的逻辑。
  • 每个通知类别的权限互相独立,互不影响。例如,通知屏蔽了爱奇艺的「新群聊消息」类通知,「常规推送」类通知依然可以发出来。

Android 已将 Channel 的逻辑纳入 Android Compatibility Definition Document (CDD) 中,意味着所有 Android 厂商都必须支持。因此 MIUI 10 也将兼容和支持相关逻辑。

2.如何适配通知类别(Channel)

官方文档已有非常详细的描述,适配步骤不再赘述,详见 https://developer.android.com/training/notify-user/channels 。

有几点值得注意:

2.1. 不要滥设类别,建议控制在 7 类以内

2.2. Channel 的名字要有可读性、有具体含义,同时避免名字重复

2.3. 如果 Channel 名字不好理解,可以使用 setDescription 来补充说明 Channel 的含义

2.4. 最好不要只设一个 Channel,那样就没有设置 Channel 的意义了。以猫眼为例,可以考虑将通知拆成多个 Channel,如下图

3. FAQ

3.1. 一定要适配通知 Channel 吗

取决于你的应用的 target API:

  • target API ≥ 26(Android 8.0):必须适配,而且必须给每条通知指定一个 Channel,否则无法发出通知。
  • target API ≤ 25(Android 7.1):可以不适配。在8.0及以上的设备,通知也能正常发出。

3.2. 一定要有通知 Channel Group 吗

不是必须的。没必要强行设置 Channel Group,应该视自己的业务需求而定。

3.3. 适配 Channel 后,在 Android 8.0 以前的设备会怎么表现

Android 8.0 以前的设备,会完全无视这个功能,因此不会带来任何兼容性问题。

3.4. 创建好 Channel 后,在代码里修改其配置,为什么会不生效

这个是 Android 对此功能增加的限制:当 Channel 已经存在时,后面的 createNotificationChannel 方法仅能更新其 name/description,以及对 importance 进行降级,其余配置均无法更新。先删除旧的 Channel,再创建新的 Channel 也无法实现对其 importance 的升级。

相关逻辑在 com/android/server/notificaton/RankingHelper.java:

@Override
public void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
        boolean fromTargetApp) {
//......
    NotificationChannel existing = r.channels.get(channel.getId());
    // Keep most of the existing settings
    if (existing != null && fromTargetApp) { // 如果已经存在同channel-id的Channel
//......
        existing.setName(channel.getName().toString()); // 则更新name和description
        existing.setDescription(channel.getDescription());
        existing.setBlockableSystem(channel.isBlockableSystem());
 
        // Apps are allowed to downgrade channel importance if the user has not changed any
        // fields on this channel yet.
        if (existing.getUserLockedFields() == 0 &&  // 并且仅当更新的importance小于原来设置的值时才更新importance
                channel.getImportance() < existing.getImportance()) {
            existing.setImportance(channel.getImportance());
        }
 
        updateConfig();
        return;
    }
//......
}


3.5. 如何判断 MIUI 版本

有以下方法:

android.os.SystemProperties.get("ro.miui.ui.version.code", "7");// 如果返回值是「8」,就是 MIUI 10

android.os.SystemProperties.get("ro.miui.ui.version.name", "");// 如果返回值是「V10」,就是 MIUI 10

3.6. 如何测试

升级到  MIUI 10 最新开发版即可,支持的机型和下载链接如下(找到对应机型的最新开发版):

小米手机MIUI 10 媒体通知适配说明

小米手机MIUI 10 媒体通知适配说明

1.媒体通知是什么

媒体通知(或称 Media template / Media style)是 Android 标准通知样式的一种,自 API 21(Android 5.0) 引入,方便用户直接控制媒体内容,常见于音乐类、广播类应用。

MIUI 10 完全兼容该通知样式,并调整了视觉风格,以符合系统风格,如下图(第一条通知)。

2. 为什么要用系统的媒体通知?

音乐类应用已经都有自己的「自定义通知」可以控制音乐,那为什么还要用系统的媒体通知?

调用系统的媒体通知,系统就能做针对性的优化,如:

  • 正在播放的媒体通知默认置顶 + 默认展开为大视图。
  • 正在播放的媒体通知默认会出现在锁屏上(置顶+大视图)。

这些都能让内容更充分地曝光,也有利于提升用户体验。

注:不同于原生 Android O 允许所有通知出现在锁屏上,MIUI 限制了出现在锁屏的通知类型,以减少用户打扰。如果需要出现在锁屏上,需要前往设置 – 通知和状态栏 – 通知管理,找到对应应用,开启‘’锁屏通知‘’。

3. 如何适配系统媒体通知

3.1 媒体通知的两种视图

媒体通知有两种视图,分别称为:

  • 标准视图 / compact view:标准的通知高度,最多显示3个按钮(actions)。
  • 大视图 / expanded view:面积更大,最多显示5个按钮。

3.2 适配媒体通知

MIUI 10的媒体通知,基于 Android O,以下是几个重要的接口:

媒体通知代码示例如下:

Notification = new Notification.Builder()
    .setContentTitle("Havana(feat.Young Thug")
    .setContentText("Camila Cabello - Havana")
    .setSmallIcon(mySmallIcon)
    .setLargeIcon(album)
    .addAction(previousAction)
    .addAction(playAction)
    .addAction(nextAction)
    .addAction(playlistAction)
    .addAction(favoriteAction)
    .setOngoing(true)
    .setStyle(newNotification.MediaStyle()
        .setShowActionsInCompactView(1,2,3)
        .setMediaSession(mySession)))
    .build();

详细接口说明见官方文档:https://developer.android.com/reference/android/app/Notification.MediaStyle

不过,以下接口在 MIUI 10 无法生效:

以上接口都可能会产生不协调的颜色,故暂时屏蔽。

4. FAQ

4.1. 如何判断 MIUI 版本

有以下方法:

android.os.SystemProperties.get("ro.miui.ui.version.code", "7");// 如果返回值是「8」,就是 MIUI 10

android.os.SystemProperties.get("ro.miui.ui.version.name", "");// 如果返回值是「V10」,就是 MIUI 10

4.2. 只有 MIUI 10 支持媒体通知吗

其实 MIUI 9 也支持媒体通知,但因为没有做好优化。所以,可以大体认为「只有 MIUI 10 支持媒体通知」,含国内版和国际版,且样式和逻辑统一。

4.3. 只要是 MIUI 10 就支持媒体通知吗?

是的。因为 Android 原生从 API 21 (android 5.0)就支持媒体通知了,详见 https://developer.android.com/reference/android/app/Notification.MediaStyle。而 MIUI 10 最低是兼容到 Android 6.0,所以只要是 MIUI 10就支持媒体通知。

4.4. MIUI 10 会禁用自定义通知吗

不会。但系统无法识别自定义通知的具体内容,只会当成普通通知处理。

4.5. MIUI 10 媒体通知的样式以后会变化吗

有可能。主要取决于:

  • Android 增加新的接口:我们后续会尽力兼容新的接口,并以此调整样式。
  • 业务需求和用户反馈。

4.6. MIUI 以前自己做的锁屏音乐界面还有用吗

在 MIUI 10 上没有用了。由于那个页面的实现方式有较多问题,因此我们在 MIUI 10 上弃用了,改由在锁屏上显示媒体通知,来实现锁屏音乐控制的需求。

4.7. 第三方应用自己做的锁屏页面(如音乐类或运动类的覆盖式)还能用吗?

可以继续使用,MIUI 10 没有限制这个能力(不过前提是开启了「锁屏显示」的权限)。但我们不建议开发者做这么一个覆盖式的页面,因为用户体验很差,还是希望能够用媒体通知替代。

4.8. 如何测试

升级到  MIUI 10 最新开发版即可,支持的机型和下载链接如下(找到对应机型的最新开发版):

小米手机MIUI 9 通知过滤适配说明

小米手机MIUI 9 通知过滤适配说明

自 MIUI 9 开始,我们新增了通知过滤的功能,接下来为大家说明该功能,以解答大家的疑问。

1. 这是什么功能

通知过滤是指通过分析用户对通知的操作,来个性化地确定通知的重要与不重要,然后将不重要的通知收纳进一个统一的页面。具体交互样式如下(MIUI 10),点击不重要通知可直接查看所有被折叠的通知。

2. 如何判断重要与否

评分模型会通过多个维度判断通知重要与否,包括但不限于:

  • 通知的文本:即标题(title) 和描述(description)
  • 该应用的通知在该设备上的历史点击率
  • 用户的属性(如年龄、性别、地域等)

评分模型会综合各个维度对特定用户的影响,个性化地给出该通知的针对该用户的“评分”, 如果“评分” > “过滤阈值”,则认为是重要通知,反之则是不重要通知。

在这些维度中,目前影响最大的维度是历史点击率,这意味着:

  • 对开发者来说,优化通知的点击率(针对设备,而不是大盘),是提高重要性的最好方法,如减少推送频率,提高内容质量等。注意,是点击率,而不是点击量。
  • 历史点击率针对的是设备,而不是大盘用户。这就要求业务使用个性化的推送策略,避免全量推送,以减小被列为不重要通知的概率。

3. 为什么在同一台手机上,同一个应用的通知,有些是重要的,有些是不重要的

如前所述,除了历史点击率,通知的评分也受通知的标题和描述影响,也就使同一应用的不同通知评分产生差别。

4. 一条通知被收进二级页,是不是就不会被点击了

不是的。从目前的数据情况来看,即便是在二级页,也有很多曝光、点击行为。

5. 这个“过滤阈值”对应的历史点击率具体是多少

如前所述,历史点击率只是评分的一个影响因子,过滤阈值可以理解为是一个特殊的评分。由于评分还受到通知文本和用户属性影响,因此无法与历史点击率直接挂勾,我们也就没法给到一个准确的值。

6. 新激活的手机和新装应用如何处理

  • 新激活的手机

新激活的手机上,初始状态各应用的历史点击率都为 0,为了避免这些通知都被直接过滤,过滤阈值在新激活后的前 14 天,会从 0 开始慢慢增长(逐小时更新)。因此新激活用户的大部分通知都不会被过滤。

  • 新装应用或新发通知

如果这是一个新安装的应用,或者之前从来没有发过通知,那么这个应用的历史点击率也为 0。为了避免这个应用的通知直接被过滤,我们加入“首 x 条保护”的规则 :即如果某个应用在当前设备的过去30天都没有产生过通知,那么,该应用在该设备的前 x 条通知,默认都是重要通知,不会被过滤。只要这些通知有1条被点击,后续通知就有很大概率成为重要通知,因此请开发者提高前几条通知的质量。 x 是一个服务端配置的值,目前默认为3。

7. 一旦成为不重要通知,是不是就没法成为重要通知了

不是的。

第一,历史点击率是一个动态变化的值,意味着:

  • 如果用户经常点击你的通知,不管它当时被判断为重要还是不重要,其历史点击率都会不断上涨,超过阈值之后,不重要通知也会变成重要。
  • 如果用户经常不点击你的通知,不管它当时被判断为重要还是不重要,其历史点击率都会不断下降,低于阈值之后,重要通知也会变成不重要。

因此开发者应持续提供优质的通知内容,以保持较高的历史点击率。

第二,历史点击率的计算范围是过去30天。举个极端例子,如果一个应用超过30天停止发送通知,那么这个应用对于系统来说,就等价于一个新安装的应用,将重新开始计算历史点击率,同时,“首 x 条保护”的规则也会生效。

8. 这个功能的影响范围

8.1. 用户范围

  • 目前仅影响国内版用户,国际版暂无此功能(仍为按时间排序)
  • 目前已随 MIUI 9 稳定版发布(仅覆盖国内用户)

8.2. 应用范围

  • 所有在通知栏发通知的应用,包括MIUI 应用和第三方应用。

9. 你们只看历史点击率吗?

不是。如前所述,模型会综合考虑非常多的维度,但目前的训练结果表明,历史点击率是影响权重较大的因子。

10. 是不是历史点击率高,这个应用的所有通知都会是重要的

  • 短期:这个说法近似正确。如前所述,目前历史点击率对“重要”与否的影响比较大, 所以短期来看,这个说法近似正确。但因为也有其他维度的影响,个别通知仍然可能出现差异。
  • 长期:这个说法不正确。未来半年会挖掘更多的维度,可以预见,历史点击率的影响权重会不断降低,那么这个说法就不成立了。

11. 用户可以手动纠正吗

  • 不感兴趣

如果用户觉得某条通知不重要,可以手动从右往左滑通知,点击“不感兴趣”,那之后这个应用的所有通知都会变成不重要了。大家应该注意到,以前的右滑屏蔽不见了(长按通知进入设置页的操作仍保留)。我们不鼓励用户直接屏蔽应用,因此弱化了这个操作,用“不感兴趣”来代替。

  • 设为重要

同样,如果用户觉得某条通知重要,可以从右往左滑通知,点击“设为重要”,那之后这个应用的所有通知都会变成重要。

12. 用户可以关闭这个功能吗

可以。前往设置 > 通知和状态栏 ,关闭“通知过滤”这个开关,就会取消该功能,同时恢复为原有的按时间排序的规则。

13.如何联系我们

可以邮件给我们的项目组 miuishell@xiaomi.com,会有同事解答相关疑问。

小米商店 MIUI 10 桌面图标上传规范

小米商店 MIUI 10 桌面图标上传规范

1. 背景

自 MIUI 10 开始,小米手机桌面默认图标将升级为全新的样式,图标更精致,圆角更小。

2. 规范

小米手机桌面是直接读取应用包内图标的,但为了保证桌面图标的视觉统一,系统会对图标作一定的截剪缩放,针对「方形」和「非方形」图标,我们有不同的处理规则,详情请见附录一和附录二。希望开发者按以下要求自查或优化现有的包内图标:

  1. 方形图标请保证是直角,且周围无透明像素。由于 MIUI 10 默认桌面图标的圆角很小,请开发者避免上传大圆角的图标。
  2. 提供更大尺寸的图标,防止图标模糊,具体建议尺寸如下:
  • xhdpi:≥ 94px
  • x​xhdpi:≥ 130px

桌面图标是用户对应用的第一印象,希望各位能够保证应用在小米手机上呈现最好的视觉效果。感谢各位开发者的支持与配合,谢谢!

3. 附录

附录一:方形图标的缩放/裁剪规则

附录二:非方形图标的缩放规则