为应用绑定通知渠道并展示消息角标

您所在的位置:网站首页 锁屏通知悬浮通知桌面角标 为应用绑定通知渠道并展示消息角标

为应用绑定通知渠道并展示消息角标

2024-07-12 17:14| 来源: 网络整理| 查看: 265

为了分清消息通知的轻重缓急,从Android8开始新增了通知渠道,并且必须指定通知渠道才能正常推送消息。一个应用允许拥有多个通知渠道,每个渠道的重要性各不相同,有的渠道消息在通知栏被折叠成小行,有的渠道消息在通知栏展示完整的大行,有的渠道消息甚至会短暂悬浮于屏幕顶部,有的渠道消息在推送时会震动手机,有的渠道消息在推送时会发出铃声,有的渠道消息则完全静默推送,这些提示差别都有赖于通知渠道的特征管理。如果不考虑定制渠道特性,仅仅弄个默认渠道好推送消息,那么只需以下三行代码即可创建默认的通知渠道:

代码语言:javascript复制        // 从系统服务中获取通知管理器         NotificationManager notifyMgr = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);         // 创建指定编号、指定名称、指定级别的通知渠道         NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);         // 创建指定的通知渠道         notifyMgr.createNotificationChannel(channel);

有了通知渠道之后,在推送消息之前使用该渠道创建对应的通知构造器,接着就能按照原方式推送消息了。使用通知渠道创建通知构造器的代码示例如下:

代码语言:javascript复制        // 创建一个通知消息的构造器         Notification.Builder builder = new Notification.Builder(this);         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {             // Android 8.0开始必须给每个通知分配对应的渠道             builder = new Notification.Builder(this, channelId);         }

当然以上代码没有指定通知渠道的具体特征,消息通知的展示情况与提示方式完全按照系统默认的。若要个性化定制不同渠道的详细特征,就得单独设置渠道对象的各特征属性。下面便是NotificationChannel提供的属性设置方法说明: setSound:设置推送通知之时的铃声,若设为null表示静音推送。 enableLights:推送消息时是否让呼吸灯闪烁。 enableVibration:推送消息时是否让手机震动。 setShowBadge:是否在应用图标的右上角展示小红点。 setLockscreenVisibility:设置锁屏时候的可见性,可见性的取值说明有:VISIBILITY_PUBLIC显示所有通知内容,Notification.VISIBILITY_PRIVATE只显示标题,Notification.VISIBILITY_SECRET不显示任何内容。 setImportance:设置通知渠道的重要性,其实NotificationChannel的构造方法已经传入了重要性,所以该方法只在变更重要性时调用。重要性的取值说明包括:IMPORTANCE_MIN最小级别,IMPORTANCE_LOW低重要性,IMPORTANCE_DEFAULT默认重要性,IMPORTANCE_HIGH高重要性。

值得注意的是,每个通知渠道一经创建,就不可重复创建,即使创建也是做无用功。因此在创建渠道之前,最好先调用通知管理器的getNotificationChannel方法,判断是否存在该编号的通知渠道,只有不存在的情况才要创建通知渠道。下面是通知渠道的创建代码例子:

代码语言:javascript复制    // 创建通知渠道。Android 8.0开始必须给每个通知分配对应的渠道     public static void createNotifyChannel(Context ctx, String channelId, String channelName, int importance) {         // 从系统服务中获取通知管理器         NotificationManager notifyMgr = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);         if (notifyMgr.getNotificationChannel(channelId) == null) { // 已经存在指定编号的通知渠道             // 创建指定编号、指定名称、指定级别的通知渠道             NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);             channel.setSound(null, null); // 设置推送通知之时的铃声。null表示静音推送             channel.enableLights(true); // 通知渠道是否让呼吸灯闪烁             channel.enableVibration(true); // 通知渠道是否让手机震动             channel.setShowBadge(true); // 通知渠道是否在应用图标的右上角展示小红点             // VISIBILITY_PUBLIC显示所有通知内容,Notification.VISIBILITY_PRIVATE只显示标题,Notification.VISIBILITY_SECRET不显示任何内容             channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); // 设置锁屏时候的可见性             channel.setImportance(importance); // 设置通知渠道的重要性级别             // 创建指定的通知渠道             notifyMgr.createNotificationChannel(channel);         }     }

尽管通知渠道提供了多种属性设置方法,但真正常用的莫过于重要性这个特征,各重要性对应的消息外观从左到右分别如下图所示,其中左图为IMPORTANCE_MIN最小级别时候的通知栏,中图为IMPORTANCE_DEFAULT默认重要性时候的通知栏,右图为IMPORTANCE_HIGH高重要性时候的顶部悬浮窗。

自从有了通知渠道,许多应用纷纷申请了多个渠道,每个渠道又有好几条消息,加起来便是许多消息。这么多的未读消息,空间有限的通知栏已然不够容纳,于是各应用又希望向用户提示未读消息的数量,好让用户知晓有没有未读消息,还有几条未读消息。 原本通知渠道提供了setShowBadge方法,可设置是否在应用图标的右上角展示小红点(此红点又称消息角标),调用该方法设置true之后,有未读消息时就显示红点,无未读消息则不显示红点。然而setShowBadge方法在国产手机上并不奏效,原因有二:其一,该方法只显示红点未显示数量;其二,该方法迟至Android8.0之后才跟着通知渠道一起推出,众多国内厂商等来不及故而早早推出了自己的红点方案。时至今日,国产手机的四大厂商包括华为、小米、OPPO、VIVO均推出了自己的消息角标方案,完全把Android官方的setShowBadge方法晾在一旁。国产手机的红点方案参考了苹果手机的红点样式,同样把消息红点放在桌面应用的右上角,并且红点内部显示当前未读消息的数量(如下面左图所示),而安卓官方的红点内部不展示数字(如下面右图所示)。

由于各厂商对消息角标的实现方案不尽相同,因此只能给他们的手机分别适配处理了。下面就以华为和小米两家的红点方案为例,依次介绍华为系手机(含华为与荣耀品牌)和小米系手机(含小米和红米品牌)的适配编码。 华为的消息角标不依赖通知推送,允许单独设置红点的展示情况,主要通过内容解析器调用华为内核的消息角标服务,详细的角标显示代码示例如下:

代码语言:javascript复制    // 华为的消息角标需要事先声明两个权限:INTERNET和CHANGE_BADGE     private 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,具体的权限配置代码如下所示:

代码语言:javascript复制               

至于小米的消息角标方案,则依赖于通知推送,必须在发送通知之时一起传送消息数量参数。为此小米给Notification类添加了一个新字段extraNotification,还添加了新方法setMessageCount,前者用于管理桌面上的消息角标,而后者能够设置角标红点的消息数量。下面是在小米手机上显示消息角标的代码例子:

代码语言:javascript复制    // 小米的消息角标需要在发送通知的时候一块调用     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();         }     }

综合上述的两种角标实现方案,形成以下的显示角标代码,可同时兼容华为系手机和小米系手机:

代码语言:javascript复制    // 在桌面上的应用图标右上角显示数字角标     public static void showMarkerCount(Context ctx, int count, Notification notify) {         showBadgeOfEMUI(ctx, count); // 华为手机EMUI系统的消息角标         // 小米手机还要进入设置里面的应用管理,开启当前App的“显示桌面图标角标”         showBadgeOfMIUI(count, notify); // 小米手机MIUI系统的消息角标     }

不管是华为方案还是小米方案,若想清除桌面上的应用红线,只要调用上面方法设置消息数量为0即可。两种方案的角标效果如下图所示,其中下面左图为华为手机上的消息角标,下面右图为小米手机上的消息角标。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3