开发 实现右上角三角形角标_给桌面应用添加消息角标
自从有了通知渠道,许多应用纷纷申请了多个渠道,每个渠道又有好几条消息,加起来便是许多消息。这么多的未读消息,空间有限的通知栏已然不够容纳,于是各应用又希望向用户提示未读消息的数量,好让用户知晓有没有未读消息,还有几条未读消息。
原本通知渠道提供了setShowBadge方法,可设置是否在应用图标的右上角展示小红点(此红点又称消息角标),调用该方法设置true之后,有未读消息时就显示红点,无未读消息则不显示红点。然而setShowBadge方法在国产手机上并不奏效,原因有二:其一,该方法只显示红点未显示数量;其二,该方法迟至Android8.0之后才跟着通知渠道一起推出,众多国内厂商等来不及故而早早推出了自己的红点方案。时至今日,国产手机的四大厂商包括华为、小米、OPPO、VIVO均推出了自己的消息角标方案,完全把Android官方的setShowBadge方法晾在一旁。国产手机的红点方案参考了苹果手机的红点样式,同样把消息红点放在桌面应用的右上角,并且红点内部显示当前未读消息的数量(如下面左图所示),而安卓官方的红点内部不展示数字(如下面右图所示)。
由于各厂商对消息角标的实现方案不尽相同,因此只能给他们的手机分别适配处理了。下面就以华为和小米两家的红点方案为例,依次介绍华为系手机(含华为与荣耀品牌)和小米系手机(含小米和红米品牌)的适配编码。
华为的消息角标不依赖通知推送,允许单独设置红点的展示情况,主要通过内容解析器调用华为内核的消息角标服务,详细的角标显示代码示例如下:
// 华为的消息角标需要事先声明两个权限:INTERNET和CHANGE_BADGEprivate static void showBadgeOfEMUI(Context ctx, int count) { try { Bundle extra = new Bundle(); // 创建一个包裹对象 extra.putString("package", BuildConfig.APPLICATION_ID); // 应用的包名 extra.putString("class", BuildConfig.APPLICATION_ID+".MainActivity"); // 应用的首屏页面路径 extra.putInt("badgenumber", count); // 应用的消息数量 Uri uri = Uri.parse("content://com.huawei.android.launcher.settings/badge/"); // 通过内容解析器调用华为内核的消息角标服务 ctx.getContentResolver().call(uri, "change_badge", null, extra); } catch (Exception e) { e.printStackTrace(); }}
为了合理使用魔改后的消息角标服务,华为规定要在AndroidManifest.xml中声明两个权限配置,包括互联网权限INTERNET,以及徽章修改权限CHANGE_BADGE,具体的权限配置代码如下所示:
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
至于小米的消息角标方案,则依赖于通知推送,必须在发送通知之时一起传送消息数量参数。为此小米给Notification类添加了一个新字段extraNotification,还添加了新方法setMessageCount,前者用于管理桌面上的消息角标,而后者能够设置角标红点的消息数量。下面是在小米手机上显示消息角标的代码例子:
// 小米的消息角标需要在发送通知的时候一块调用private static void showBadgeOfMIUI(int count, Notification notify) { try { // 利用反射技术获得额外的新增字段extraNotification Field field = notify.getClass().getDeclaredField("extraNotification"); // 该字段为Notification类型,下面获取它的实例对象 Object extraNotification = field.get(notify); // 利用反射技术获得额外的新增方法setMessageCount Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class); // 利用反射技术调用实例对象的setMessageCount方法,设置角标红点的消息数量 method.invoke(extraNotification, count); } catch (Exception e) { e.printStackTrace(); }}
综合上述的两种角标实现方案,形成以下的显示角标代码,可同时兼容华为系手机和小米系手机:
// 在桌面上的应用图标右上角显示数字角标public static void showMarkerCount(Context ctx, int count, Notification notify) { showBadgeOfEMUI(ctx, count); // 华为手机EMUI系统的消息角标 // 小米手机还要进入设置里面的应用管理,开启当前App的“显示桌面图标角标” showBadgeOfMIUI(count, notify); // 小米手机MIUI系统的消息角标}
不管是华为方案还是小米方案,若想清除桌面上的应用红线,只要调用上面方法设置消息数量为0即可。两种方案的角标效果如下图所示,其中下面左图为华为手机上的消息角标,下面右图为小米手机上的消息角标。
上一篇: 回溯算法的一些问题