美文网首页Android开发学习Android技术知识Android知识
Android应用图标上的小红点Badge亲自实践

Android应用图标上的小红点Badge亲自实践

作者: 轻轻笑声 | 来源:发表于2017-07-27 17:45 被阅读704次

    现在Android中有许多的应用仿苹果的在应用图标上显示小红点。当然有着一些手机ROM对小红点的支持,比如小米,三星等。google的api是没有提供这项工能的,这项功能一般都是厂商自己定制的,所以让开发者着实头痛,我也是弄了2天,不是所有的机型都可以.以后再一点点完善吧.希望对读文章的人,或也在受此困惑的人有点帮助!

    效果图:(DODO那个是我的应用,小米miui8测试)

    GIF.gif

    直接上代码吧,代码中有注释:

    BadgeUtil类:

    public class BadgeUtil {
        private BadgeUtil() throws InstantiationException {
            throw new InstantiationException("This class is not for instantiation");
        }
    
        /**
         * 设置Badge 目前支持Launcher
         */
        public static void setBadgeCount(Context context, int count, int iconResId) {
            if (count <= 0) {
                count = 0;
            } else {
                count = Math.max(0, Math.min(count, 99));
            }
    
            if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) {
                setBadgeOfMIUI(context, count, iconResId);
            } else if (Build.MANUFACTURER.equalsIgnoreCase("sony")) {
                setBadgeOfSony(context, count);
            } else if (Build.MANUFACTURER.toLowerCase().contains("samsung") ||
                    Build.MANUFACTURER.toLowerCase().contains("lg")) {
                setBadgeOfSumsung(context, count);
            } else if (Build.MANUFACTURER.toLowerCase().contains("htc")) {
                setBadgeOfHTC(context, count);
            } else if (Build.MANUFACTURER.toLowerCase().contains("nova")) {
                setBadgeOfNova(context, count);
            }else if (Build.MANUFACTURER.toLowerCase().contains("OPPO")) {//oppo
                //setBadgeOfOPPO(context, count);
            }else if (Build.MANUFACTURER.toLowerCase().contains("LeMobile")) {//乐视
    
            }
            else if (Build.MANUFACTURER.toLowerCase().contains("vivo")) {
                setBadgeOfVIVO(context, count);
            }else if (Build.MANUFACTURER.toLowerCase().contains("HUAWEI")||Build.BRAND.equals("Huawei")||Build.BRAND.equals("HONOR")) {//华为
                setHuaweiBadge(context, count);
            }else if (Build.MANUFACTURER.toLowerCase().contains("")) {//魅族
    
            }else if (Build.MANUFACTURER.toLowerCase().contains("")) {//金立
    
            }else if (Build.MANUFACTURER.toLowerCase().contains("")) {//锤子
    
            }else {
                //Toast.makeText(context, "Not Found Support Launcher", Toast.LENGTH_LONG).show();
            }
        }
    
        /**
         * 设置MIUI的Badge
         */
        private static void setBadgeOfMIUI(Context context, int count, int iconResId) {
            NotificationManager mNotificationManager = (NotificationManager) context
                    .getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
            builder.setContentTitle("标题").setContentText("消息正文").setSmallIcon(iconResId);
            Notification notification = builder.build();
            try {
                Field field = notification.getClass().getDeclaredField("extraNotification");
                Object extraNotification = field.get(notification);
                Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
                method.invoke(extraNotification, count);
            } catch (Exception e) {
                e.printStackTrace();
            }
            mNotificationManager.notify(0, notification);
        }
    
        /**
         * 设置索尼的Badge
         * 需添加权限:<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
         */
        private static void setBadgeOfSony(Context context, int count) {
            String launcherClassName = getLauncherClassName(context);
            if (launcherClassName == null) {
                return;
            }
            boolean isShow = true;
            if (count == 0) {
                isShow = false;
            }
            Intent localIntent = new Intent();
            localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
            localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", isShow);//是否显示
            localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);//启动页
            localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(count));//数字
            localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());//包名
            context.sendBroadcast(localIntent);
        }
    
        /**
         * 设置三星的Badge\设置LG的Badge
         */
        private static void setBadgeOfSumsung(Context context, int count) {
            // 获取你当前的应用
            String launcherClassName = getLauncherClassName(context);
            if (launcherClassName == null) {
                return;
            }
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", count);
            intent.putExtra("badge_count_package_name", context.getPackageName());
            intent.putExtra("badge_count_class_name", launcherClassName);
            context.sendBroadcast(intent);
        }
    
        /**
         * 设置HTC的Badge
         */
        private static void setBadgeOfHTC(Context context, int count) {
            Intent intentNotification = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
            ComponentName localComponentName = new ComponentName(context.getPackageName(), getLauncherClassName(context));
            intentNotification.putExtra("com.htc.launcher.extra.COMPONENT", localComponentName.flattenToShortString());
            intentNotification.putExtra("com.htc.launcher.extra.COUNT", count);
            context.sendBroadcast(intentNotification);
    
            Intent intentShortcut = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
            intentShortcut.putExtra("packagename", context.getPackageName());
            intentShortcut.putExtra("count", count);
            context.sendBroadcast(intentShortcut);
        }
    
        /**
         * 设置Nova的Badge
         */
        private static void setBadgeOfNova(Context context, int count) {
            ContentValues contentValues = new ContentValues();
            contentValues.put("tag", context.getPackageName() + "/" + getLauncherClassName(context));
            contentValues.put("count", count);
            context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"),
                    contentValues);
        }
    
        /**
         * 设置vivo的Badge :vivoXplay5 vivo x7无效果
         */
        private static void setBadgeOfVIVO(Context context,int count){
            try {
                Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
                intent.putExtra("packageName", context.getPackageName());
                String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
                intent.putExtra("className", launchClassName); intent.putExtra("notificationNum", count);
                context.sendBroadcast(intent);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        /**
         *设置oppo的Badge :oppo角标提醒目前只针对内部软件还有微信、QQ开放,其他的暂时无法提供
         */
        private static void setBadgeOfOPPO(Context context,int count){
            try {
                Bundle extras = new Bundle();
                extras.putInt("app_badge_count", count);
                context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", String.valueOf(count), extras);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 设置华为的Badge :mate8 和华为 p7,honor畅玩系列可以,honor6plus 无效果
         */
        public static void setHuaweiBadge(Context context, int count)
        {
            try {
                Bundle bundle = new Bundle();
                bundle.putString("package", context.getPackageName());
                String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
                bundle.putString("class", launchClassName);
                bundle.putInt("badgenumber", count);
                context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bundle);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void setBadgeOfMadMode(Context context, int count, String packageName, String className) {
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", count);
            intent.putExtra("badge_count_package_name", packageName);
            intent.putExtra("badge_count_class_name", className);
            context.sendBroadcast(intent);
        }
    
        /**
         * 重置Badge
         */
        public static void resetBadgeCount(Context context, int iconResId) {
            setBadgeCount(context, 0, iconResId);
        }
    
        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;
        }
    }
    

    权限:

        <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
        <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
        <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
        <!-- 申请华为角标权限  -->
        <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
        <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
        <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" />
    

    总结:

    小米,三星,索尼,htc,朵唯.手中有的手机基本小红点功能都是没有问题的.
    oppo:厂商不提供此功能,只对于市面上排名前5的商用聊天提供,还说对企业内部的im会提供此功能,不过必须要集成oppo证书.
    华为:与oppo说法一样,但是按上面代码测试,华为的部分机型是可以实现的.荣耀6和6p没有效果.
    vivo:部分手机有效果,vivo xplay5 x7 没有效果.
    至于锤子,魅族,金立等,网上说是不支持此功能的,,因为没有测试机,并没有验证.
    乐视:有自带效果(没有询问客服,就不给人添乱了!)
    希望对广大开发者有帮助!

    相关文章

      网友评论

      • 93d24008a396:楼主 oppo的现在只支持自己的软件和qq、微信吗?在哪里看到的。。跪求
        93d24008a396:@简曼玉 原来如此原来如此 感谢感谢
        轻轻笑声:要去,问oppo的客服,寻求商务合作才可以.

      本文标题:Android应用图标上的小红点Badge亲自实践

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