Android 桌面角标在各大品牌机型上的实现

    xiaoxiao2021-04-13  31

    由于角标在Android原生的系统中没有支持,所以各个Android手机厂商各自为政。

    正如很多资料所说,这一功能完全是效仿IOS,Android本不存在的,对于不支持的厂商如魅族、中兴、酷派,必须为他们不盲目跟风而点赞。

    做起适配来,真的很麻烦,要针对各个厂商逐个去写以及测试。

    目前做到支持小米、华为、三星、LG、VIVO、ZUK、HTC、NOVA等厂商的Andorid系统

    效果如下图所示

    特别说明一下小米自MIUI6.0以后,角标的显示和通知栏Notification绑在一起。目前我发现的做法,就只有小米需要和Notification绑在一起才能生效。

    不过我在这里的例子因产品需求,全部机型的做法都把Notification绑上。

    消息通知ID

    private int MQTT_IM_NOTIFICATION_ID=1007;

    通知栏Notification的定义

    String content = 2 + "个联系人发了" + i + "条消息"; NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext()); builder.setSmallIcon(R.drawable.chat_notify_icon); builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)); builder.setTicker("收到" + i + "条消息"); builder.setWhen(System.currentTimeMillis()); Intent intent = new Intent(getBaseContext(), MainActivity.class); intent.setAction(getApplicationContext().getPackageName()); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pi); builder.setContentTitle(getResources().getText(R.string.app_name)); builder.setContentText(content); final Notification n = builder.build(); int defaults = Notification.DEFAULT_LIGHTS; defaults |= Notification.DEFAULT_SOUND; defaults |= Notification.DEFAULT_VIBRATE; n.defaults = defaults; n.flags = Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_AUTO_CANCEL;

    厂商

    private static String SYSTEM_XIAOMI="XIAOMI"; private static String SYSTEM_SAMSUNG="SAMSUNG"; private static String SYSTEM_HUAWEI_HONOR="HONOR"; private static String SYSTEM_HUAWEI="HUAWEI"; private static String SYSTEM_NOVA="NOVA"; private static String SYSTEM_SONY="SONY"; private static String SYSTEM_VIVO="VIVO"; private static String SYSTEM_OPPO="OPPO"; private static String SYSTEM_LG="LG"; private static String SYSTEM_ZUK="ZUK"; private static String SYSTEM_HTC="HTC";

    厂商获取

    OSName=android.os.Build.BRAND.trim().toUpperCase();

    类名的获取

    主要是得到Activity名字,得到完整的包名、类名

    //获取类名 public static String getLauncherClassName(Context context) { PackageManager packageManager = context.getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.setPackage(context.getPackageName()); intent.addCategory(Intent.CATEGORY_LAUNCHER); ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); if (info == null) { info = packageManager.resolveActivity(intent, 0); } return info.activityInfo.name; }

    广播

    //广播 public static boolean canResolveBroadcast(Context context, Intent intent) { PackageManager packageManager = context.getPackageManager(); List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0); return receivers != null && receivers.size() > 0; }

    小米

    特别注意,小米的通知栏提示需要延时操作才会出现角标,但是偶尔还是没法出现,暂时没有特别好的解决办法,不过目前能保证做到较高的成功率。

    除了小米以外,其他实现基本没什么问题。

    //小米 private static void setBadgeOfXiaomi(final Context context,final Notification notification,final int NOTIFI_ID,final int num){ new Handler().postDelayed(new Runnable() { @Override public void run() { try { Field field = notification.getClass().getDeclaredField("extraNotification"); Object extraNotification = field.get(notification); Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class); method.invoke(extraNotification, num); } catch (Exception e) { e.printStackTrace(); Log.e("Xiaomi" + " Badge error", "set Badge failed"); } // mNotificationManager.notify(0,notification); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); } },550); }

    三星 & LG

    //三星和LG private static void setBadgeOfSamsung(Context context,Notification notification, int NOTIFI_ID,int num) { // 获取你当前的应用 String launcherClassName = getLauncherClassName(context); if (launcherClassName == null) { return; } try { Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); intent.putExtra("badge_count", num); intent.putExtra("badge_count_package_name", context.getPackageName()); intent.putExtra("badge_count_class_name", launcherClassName); context.sendBroadcast(intent); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("SAMSUNG" + " Badge error", "set Badge failed"); } }

    华为

    华为及其荣耀系列通用,不需要官网认证

    //华为 系列 private static void setBadgeOfHuaWei(Context context, Notification notification,int NOTIFI_ID,int num) { try{ Bundle localBundle = new Bundle(); localBundle.putString("package", context.getPackageName()); localBundle.putString("class", getLauncherClassName(context)); localBundle.putInt("badgenumber", num); context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, localBundle); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch(Exception e){ e.printStackTrace(); Log.e("HUAWEI" + " Badge error", "set Badge failed"); } }

    索尼

    //索尼 private static void setBadgeOfSony(Context context,Notification notification,int NOTIFI_ID, int num){ String numString=""; String activityName = getLauncherClassName(context); if (activityName == null){ return; } Intent localIntent = new Intent(); // int numInt = Integer.valueOf(num); boolean isShow = true; if (num < 1){ numString = ""; isShow = false; }else if (num > 99){ numString = "99"; } try { localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", isShow); localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE"); localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", activityName); localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", numString); localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName()); context.sendBroadcast(localIntent); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("SONY" + " Badge error", "set Badge failed"); } }

    VIVO

    //VIVO private static void setBadgeOfVIVO(Context context,Notification notification,int NOTIFI_ID,int num){ try { Intent localIntent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM"); localIntent.putExtra("packageName", context.getPackageName()); localIntent.putExtra("className", getLauncherClassName(context)); localIntent.putExtra("notificationNum", num); context.sendBroadcast(localIntent); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("VIVO" + " Badge error", "set Badge failed"); } }

    OPPO

    目前只支持部分机型

    //OPPO *只支持部分机型 private static void setBadgeOfOPPO(Context context, Notification notification,int NOTIFI_ID,int num){ try { if (num == 0) { num = -1; } Intent intent = new Intent("com.oppo.unsettledevent"); intent.putExtra("pakeageName", context.getPackageName()); intent.putExtra("number", num); intent.putExtra("upgradeNumber", num); if (canResolveBroadcast(context, intent)) { context.sendBroadcast(intent); } else { try { Bundle extras = new Bundle(); extras.putInt("app_badge_count", num); context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extras); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); } catch (Throwable th) { Log.e("OPPO" + " Badge error", "unable to resolve intent: " + intent.toString()); } } }catch (Exception e){ e.printStackTrace(); Log.e("OPPO" + " Badge error", "set Badge failed"); } } ZUK

    //ZUK private static void setBadgeOfZUK(Context context,Notification notification,int NOTIFI_ID, int num){ final Uri CONTENT_URI = Uri.parse("content://com.android.badge/badge"); try { Bundle extra = new Bundle(); extra.putInt("app_badge_count", num); context.getContentResolver().call(CONTENT_URI, "setAppBadgeCount", null, extra); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("ZUK" + " Badge error", "set Badge failed"); } } HTC

    //HTC private static void setBadgeOfHTC(Context context,Notification notification,int NOTIFI_ID,int num){ try { Intent intent1 = new Intent("com.htc.launcher.action.SET_NOTIFICATION"); intent1.putExtra("com.htc.launcher.extra.COMPONENT", context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().flattenToShortString()); intent1.putExtra("com.htc.launcher.extra.COUNT", num); Intent intent = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT"); intent.putExtra("packagename", context.getPackageName()); intent.putExtra("count", num); if (canResolveBroadcast(context, intent1) || canResolveBroadcast(context, intent)) { context.sendBroadcast(intent1); context.sendBroadcast(intent); } else { Log.e("HTC" + " Badge error", "unable to resolve intent: " + intent.toString()); } NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("HTC" + " Badge error", "set Badge failed"); } }

    NOVA

    //NOVA private static void setBadgeOfNOVA(Context context,Notification notification,int NOTIFI_ID,int num){ try{ ContentValues contentValues = new ContentValues(); contentValues.put("tag", context.getPackageName()+ "/" +getLauncherClassName(context)); contentValues.put("count", num); context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), contentValues); NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("NOVA" + " Badge error", "set Badge failed"); } }

    其他

    做个备案吧,这个真不一定能生效,只能从大多数的做法里摸规律

    //其他 private static void setBadgeOfDefault(Context context,Notification notification,int NOTIFI_ID,int num){ try { Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); intent.putExtra("badge_count", num); intent.putExtra("badge_count_package_name", context.getPackageName()); intent.putExtra("badge_count_class_name", getLauncherClassName(context)); if (canResolveBroadcast(context, intent)) { context.sendBroadcast(intent); } else { Log.e("Default" + " Badge error", "unable to resolve intent: " + intent.toString()); } NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE)); if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID); }catch (Exception e){ e.printStackTrace(); Log.e("Default" + " Badge error", "set Badge failed"); } } github :  https://github.com/Cedric-Xuan/SNSNotificationBadge

    转载请注明原文地址: https://ju.6miu.com/read-668960.html

    最新回复(0)