Android Badge技术分析
Badge红点最初来自于IOS的UX设计之中,早期版本的Android原生并没有这个设计,从Android O(SDK 26)开始,Google才开始提供官方的API。在这之前我们看到的各种手机系统上的Badge实际上是各个手机厂商的Rom中,自己对Launcher添加了这个Feature,因此也造成了一些问题,比如碎片化严重,没有统一的API。APP如果要使用Badge需要针对不同厂商的ROM进行定向开发。下面是目前主流的手机厂商Badge功能的具体实现。
API 26之前:
在API 26之前,由于没有统一的系统API,需要对判断手机型号,并定向处理。主要的方式有三种:第一种是通过反射调用厂商自己定义的framework方法(如小米),第二种是发送Badge的对应广播(如三星),第三种是通过ContentProvider实现(如华为)。有的手机ROM甚至还要添加特定的权限才能够生效(如华为)。根据测试结果,实际还是有很多手机上无法生效。一方面可能是因为一些手机ROM中没有Badge的Feature,另一方面是厂商对这一权限有比较严格的限制,比如设置白名单,默认禁止通知等。
@Unreliable
public class NotificationBadgeUtil {
public static final String TAG = "NotificationBadgeUtil";
private static final String SYSTEM_XIAOMI = "XIAOMI";
private static final String SYSTEM_SAMSUNG = "SAMSUNG";
private static final String SYSTEM_HUAWEI_HONOR = "HONOR";
private static final String SYSTEM_HUAWEI = "HUAWEI";
private static final String SYSTEM_NOVA = "NOVA";
private static final String SYSTEM_SONY = "SONY";
private static final String SYSTEM_VIVO = "VIVO";
private static final String SYSTEM_OPPO = "OPPO";
private static final String SYSTEM_LG = "LG";
private static final String SYSTEM_ZUK = "ZUK";
private static final String SYSTEM_HTC = "HTC";
private static boolean hasInit = false;
private static String OSName = null;
/**
* The static method to show a badge while using notification.
*
* Google provide system API for badges works in launcher since Android O,
* if SDK version is older than Android O, you can using variant phone custom
* launcher badge ways like dealing in this method. But some specific phone
* models seems don`t support system API even though API over Android O, like
* my HUAWEI P9 Android O.
*
* @param context Context for notification dependence.
* @param notification Notification object correspond to badge.
* @param NOTIFICATION_ID The notification channel id.
* @param num The count of badges. Cancel notification if count is 0.
*/
public static void showBadge(Context context, Notification notification, int NOTIFICATION_ID, int num) {
if (!hasInit) {
init();
}
OSName = Build.BRAND.trim().toUpperCase();
if (notification != null) {
if (num < 0) num = 0;
if (num > 99) num = 99;
Log.e("system_name", OSName);
if (OSName != null) {
if (OSName.equals(SYSTEM_XIAOMI)) {
setBadgeOfXiaomi(context, notification, NOTIFICATION_ID, num);
} else if (OSName.equals(SYSTEM_SAMSUNG) || OSName.equals(SYSTEM_LG)) {
setBadgeOfSamsung(context, notification, NOTIFICATION_ID, num);
} else if (OSName.equals(SYSTEM_HUAWEI_HONOR) || OSName.equals(SYSTEM_HUAWEI)) {
setBadgeOfHuaWei(context, notification, NOTIFICATION_ID, num);
} else if (OSName.equals(SYSTEM_SONY)) {
setBadgeOfSony(context, notification, NOTIFICATION_ID, num);
} else if (OSName.equals(SYSTEM_VIVO)) {
setBadgeOfVIVO(context, notification, NOTIFICATION_ID, num);
} else if (OSName.equals(SYSTEM_OPPO)) {
setBadgeOfOPPO(context, notification, NOTIFICATION_ID, num);
} else if (OSName.equals(SYSTEM_ZUK)) {
setBadgeOfZUK(context, notification, NOTIFICATION_ID, num);