美文网首页Android笔记
Android 桌面角标在各大品牌机型上的实现

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

作者: Cedric_h | 来源:发表于2019-07-25 03:16 被阅读0次

    原文:https://blog.csdn.net/uyy203/article/details/70160752

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

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

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

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

    效果如下图所示


    image.png

    特别说明一下小米自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;
    

    厂商

    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;
    
    

    厂商获取

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

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

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

        //小米
        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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/nmnqrctx.html