您的位置:首页 > 移动开发 > 微信开发

关于Android类似qq和微信那种在桌面图标右上角更新数字的研究

2016-03-15 18:14 471 查看
记录下这个需求的研究 写的超级随意 大家凑合看 不懂再问 一起探讨

因为我们的产品也需要有即时通讯了 消息更新不可避免
首先 要实现这个功能 当然是要借助系统的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源码吧 也许能事半功倍呢 虽然有点不厚道 哈哈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: