关于Android类似qq和微信那种在桌面图标右上角更新数字的研究
Posted wuhongqi0012
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Android类似qq和微信那种在桌面图标右上角更新数字的研究相关的知识,希望对你有一定的参考价值。
记录下这个需求的研究 写的超级随意 大家凑合看 不懂再问 一起探讨因为我们的产品也需要有即时通讯了 消息更新不可避免 首先 要实现这个功能 当然是要借助系统的Launcher。
而谷歌并没有开放出这个标准的接口或者方法 于是各大厂商都对Launcher这块做了各自的改动,这也给第三方开发者想要统一处理这个需求加大了难度。 网上demo也有一些 大部分是通过发送广播的方式,来通知系统更新图标上的数字
比如我之前在github上找到一个demoTestShortCut 就很不错, 针对三星(亲测)、索尼、小米 小米貌似在miui系统里已经内部处理了这种情况 发通知栏消息的时候 会自动加数字 /*** * 三星手机:应用图标的快捷方式上加数字 * @param context * @param num */ public static void samsungShortCut(Context context, String num) int numInt = Integer.valueOf(num); if (numInt < 1) num = "0"; else if (numInt > 99) num = "99"; String activityName = getLaunchActivityName(context); Intent localIntent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); localIntent.putExtra("badge_count", Integer.parseInt(num)); localIntent.putExtra("badge_count_package_name", context.getPackageName()); localIntent.putExtra("badge_count_class_name", activityName); context.sendBroadcast(localIntent);
/*** * 索尼手机:应用图标的快捷方式上加数字 * @param context * @param num */ public static void sonyShortCut(Context context, String num) String activityName = getLaunchActivityName(context); if (activityName == null) return; Intent localIntent = new Intent(); int numInt = Integer.valueOf(num); boolean isShow = true; if (numInt < 1) num = ""; isShow = false; else if (numInt > 99) num = "99"; 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", num); localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName()); context.sendBroadcast(localIntent);
/*** * 在小米应用图标的快捷方式上加数字<br> * * * @param context * @param num 显示的数字:大于99,为"99",当为""时,不显示数字,相当于隐藏了)<br><br> * * 注意点: * context.getPackageName()+"/."+clazz.getSimpleName() (这个是启动activity的路径)中的"/."不能缺少 * */ public static void xiaoMiShortCut(Context context,Class<?> clazz, String num) Log.e(TAG, "xiaoMiShortCut...."); Intent localIntent = new Intent("android.intent.action.APPLICATION_MESSAGE_UPDATE"); localIntent.putExtra("android.intent.extra.update_application_component_name", context.getPackageName()+"/."+clazz.getSimpleName()); if(TextUtils.isEmpty(num)) num = ""; else int numInt = Integer.valueOf(num); if (numInt > 0) if (numInt > 99) num = "99"; else num = "0"; localIntent.putExtra("android.intent.extra.update_application_message_text", num); context.sendBroadcast(localIntent);
但没办法,我们的产品需要针对的是下面这三个厂商 华为 OPPO VIVO 使用上面的demo确没办法做到,所以还得继续研究 于是在找了很多资料没有结果以后 我决定反编译QQ和微信的源码来研究 (注:有很多机型qq和微信也没办法做到这个需求) 先从qq开始 反编译以后 在源码里搜索了很多关键字 终于让我找到了这个类 BadgeUtilImpl.class 太兴奋了。
public static void changeOPPOBadge(Context paramContext, int paramInt) int i = 99; if (!isEnabled(paramContext)); for (int j = 0; ; j = paramInt) if (j > i); while (true) if (QLog.isColorLevel()) QLog.d("BadgeUtilImpl", 2, "changeOPPOBadge mcount=" + i); try Bundle localBundle = new Bundle(); localBundle.putInt("app_badge_count", i); paramContext.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, localBundle); return; i = j; catch (Exception localException) QLog.d("BadgeUtilImpl", 2, "OPPOBadge badge get a crash" + localException.getMessage()); return;
public static String getLauncherClassName(Context paramContext) String str; if (!TextUtils.isEmpty(mLauncherClassName)) str = mLauncherClassName; while (true) return str; PackageManager localPackageManager = paramContext.getPackageManager(); Intent localIntent = new Intent("android.intent.action.MAIN"); localIntent.addCategory("android.intent.category.LAUNCHER"); try Iterator localIterator = localPackageManager.queryIntentActivities(localIntent, 0).iterator(); while (true) if (localIterator.hasNext()) ResolveInfo localResolveInfo = (ResolveInfo)localIterator.next(); if (!localResolveInfo.activityInfo.applicationInfo.packageName.equalsIgnoreCase(paramContext.getPackageName())) continue; str = localResolveInfo.activityInfo.name; mLauncherClassName = str; if (!QLog.isColorLevel()) break; QLog.d("BadgeUtilImpl", 2, "getLauncherClassName" + mLauncherClassName); return str; catch (Exception localException) return null; return null;
public static void setBadge(Context paramContext, int paramInt) setBadge(paramContext, paramInt, false);
public static void setBadge(Context paramContext, int paramInt, boolean paramBoolean) if (QLog.isColorLevel()) QLog.d("BadgeUtilImpl", 2, "setBadge count=" + paramInt + "|forceSet=" + paramBoolean); if ((!isEnabled(paramContext)) && (!paramBoolean)); do return; if (isQQLanucher()) setQQLauncherBadges(paramContext, paramInt); if (Build.MANUFACTURER.equalsIgnoreCase("ZUK")) changeZUKBadge(paramContext, paramInt); if (islenovoLanucher("com.lenovo.launcher")) setLenovoBadge(paramContext, paramInt); if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) changeMIBadge(paramContext, paramInt); return; if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) setSamsungBadge(paramContext, paramInt); return; if (!Build.MANUFACTURER.equalsIgnoreCase("huawei")) continue; setHuaweiBadge(paramContext, paramInt); return; while (!Build.MANUFACTURER.equalsIgnoreCase("OPPO")); changeOPPOBadge(paramContext, paramInt);
public static void setHuaweiBadge(Context paramContext, int paramInt) while (true) try if (!QLog.isColorLevel()) continue; QLog.d("BadgeUtilImpl", 2, "huawiBadge mcount=" + paramInt); String str = getLauncherClassName(paramContext); if (str == null) return; Bundle localBundle = new Bundle(); localBundle.putString("package", paramContext.getPackageName()); localBundle.putString("class", str); localBundle.putInt("badgenumber", paramInt); paramContext.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, localBundle); return; catch (Throwable localThrowable) return; if (paramInt <= 99) continue; paramInt = 99;
qq这里面有针对华为和OPPO的
我用华为荣耀6亲测过有效 但是华为Meta却不行(我试过 微信和qq同样不行)
OPPO的没效果 提示没有此Uri (OPPO r7 qq和微信及其他第三方app 也都不能显示数字)
再来看看vivo qq没法显示数字 但是微信会显示 于是驱使我研究微信的源码 微信的源码混淆的比较多 找起来比qq费事 不过还是让我找到了线索 在这个包目录下com.tencent.mm.booter.notification 找到了类文件d 找到了这段代码 Intent localIntent1 = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM"); localIntent1.putExtra("packageName", context.getPackageName()); localIntent1.putExtra("className", MainActivity.class.getName()); localIntent1.putExtra("notificationNum", paramInt); context.sendBroadcast(localIntent1);
经测试 vivo 也可以显示了..
总结一句:网上找不到资料的时候 就去研究第三方app源码吧 也许能事半功倍呢 虽然有点不厚道 哈哈
以上是关于关于Android类似qq和微信那种在桌面图标右上角更新数字的研究的主要内容,如果未能解决你的问题,请参考以下文章