Android 桌面图标添加未读消息角标APP角标最佳实践
Android 桌面图标添加未读消息角标APP角标最佳实践
本项目的完整演示代码 https://github.com/benchegnzhou/AndroidDevelomentArtDemo
最近为一个为应用添加角标的是产品需求大为苦恼,不禁感叹Android机型真的多样,由于Android的开源导致各大平台和厂商纷纷定义了自家的rom,这本应是一件利好(对广大的用户),毕竟开源产生了无穷的趣味性,当时对咱们开发者来说,有限的时间内做到适配的面面俱到还是一件比较不容易的事情的。
拿到这个需求我想往常一样一同各种各样的百度,确实可以找到很多的文章,运行之后各种的适配不兼容,github了一同,奈何国内的开发者的研究水平还是欠缺了写,实在没有办法只有自己造*了。
目录
5. 为什么我的手机是华为但是,设置后不管用 —— launcher决定适配代码
6. 既然我们成功的获取到了手机的launcher,剩下的任务和简单,我们需要做的就是去各个厂家的官网或者对应的开放(开发)平台瞅瞅,找到对应的API说明
最近有点感想,不管对不对,仅仅最为自己的理解不同意的地方希望大家包容:
本次的开发,或许给了自己很多的启发,毕竟自己开发Android已经有3年多的时间了,我曾和很多的朋友交流,当自己的进步遇到一定的瓶颈的时候,应该怎样去学习,首先说遇到瓶颈是必然的事情,当我们的技能水准达到与自己接触到的绝大部分人水平一样甚至在一些地方超过他们的时候,这时候我们往往不能还像开始那样,遇到一个问题简单的百度一下然后ok,能用就可以,这个时候我们往往会对自己产生更高的要求(有时候这种要求是公司给的),要求我们不仅仅是那部分简单接受的小白鼠,更应该是一个可以去钻研,去创新,去发现的人,简单来说以前的我们总是可以依靠前辈们造出的*、写好的文章,而技术达到一定的水准后应该主动的研究原理,读懂源码,出现一个问题直到从哪里才能找到第一手珍贵的资料,这才是我们作为一个真正的开发者应该具备呢,不然要是一直都跟在大多数人的后面怎么才能超过他们呀。
下载体验完整版本demo,点击这里 https://github.com/benchegnzhou/AndroidDevelomentArtDemo
本项目的完整演示代码 https://github.com/benchegnzhou/AndroidDevelomentArtDemo
手机厂商(launcher) | 是否支持(Y/N) | launcher package name |
---|---|---|
HUAWEI | Y | com.huawei.android.launcher |
XIOAMI | Y* | com.miui.home |
OPPO | Y* | |
VIVO | N* | |
Y* | com.google.android.apps.nexuslauncher | |
MEIZU | N | |
SAMSUNG | Y* | com.sec.android.app.launcher |
*:有特殊情况,会在第三节中详细说明
实际上Android系统之前是从未提供过这种类似于iOS的角标功能的,但是由于很多国产手机厂商都喜欢跟风iOS,因此各种国产手机ROM都纷纷推出了自己的角标功能。
可是国产手机厂商虽然可以订制ROM,但是却没有制定API的能力,因此长期以来都没有一个标准的API来实现角标功能,很多都是要通过向系统发送广播来实现的,而各个手机厂商的广播标准又不一致,经常导致代码变得极其混杂。
值得高兴的是,从8.0系统开始,Google制定了Android系统上的角标规范,也提供了标准的API,长期让开发者头疼的这个问题现在终于可以得到解决了。
5. 为什么我的手机是华为但是,设置后不管用 —— launcher决定适配代码
判断当前launcher,这里需要注意的是,是否支持角标并不与手机厂商有关,而是你当前使用的launcher开发厂商有关
比如:你用着华为手机,却用着魅族的launcher,那肯定是不会成功的显示出桌面角标的
相反的,你用着某一款手机却用着华为的launcher,一样可以显示出桌面图标角标
-
应用的桌面图标是由launcher 决定的,launcher其实就是一个系统级别的应用APP(和我们的APP木有本质区别啦),他可以管理APP的图标样式,说到这里你是不是恍然大悟,实现这个功能需要具备两个条件
-
1.首先这个 launcher 要支持小圆点图标
-
2.其次,我们只要能够完成与这个应用之间进行通信就好了,幸运的是国产厂商一般在后期的版本完成了这个兼容(不兼容的老用户估计也不会对这个痛点敏感的,舍弃吧),基本都是清一色的广播的形式,但是其中有一些差异,这也是适配复杂的原因,甚至同一个品牌适配在各个版本时期也会有所不同;在android O后Google开发了系统级别的API,这个的适配就相对简单许多了。
获取当前launcher包名的方法
public static String getLauncherPackageName() {
//获取ApplicationContext
final Context context = App.getInstance().getBaseContext();
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);
if (res.activityInfo == null) {
// should not happen. A home is always installed.
return null;
}
if (res.activityInfo.packageName.equals("android")) {
return null;
} else {
return res.activityInfo.packageName;
}
}
6. 既然我们成功的获取到了手机的launcher,剩下的任务和简单,我们需要做的就是去各个厂家的官网或者对应的开放(开发)平台瞅瞅,找到对应的API说明
官方文档:https://developer.huawei.com/consumer/cn/devservice/doc/30802
private void setHUAWEIIconBadgeNum(int count) throws Exception {
final Context context = App.getInstance().getBaseContext();
Bundle bunlde = new Bundle();
bunlde.putString("package", context.getPackageName());
bunlde.putString("class", CappUtils.getLaunchIntentForPackage());
bunlde.putInt("badgenumber", count);
context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bunlde);
}
6.2 小米(红米)
官方文档:https://dev.mi.com/console/doc/detail?pId=939
private Notification setXIAOMIIconBadgeNum(int count, Notification notification) throws Exception {
Field field = notification.getClass().getDeclaredField("extraNotification");
Object extraNotification = field.get(notification);
Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
method.invoke(extraNotification, count);
return notification;
}
小米实现时,需要注意一下几点:
必须发送notification
只支持MIUI6-10(网上有针对6以下的砖,我没法验证,所以这里就不贴出来了)
当APP处于前台时,数字会自动清空(因此,APP必须处于后台时才可以设置成功)
为什么这么多限制,与我用的邮箱或那些聊天软件不一样?
我会在最后一节吐槽这个事
6.3 OPPO
首先,官方客服和我说他们可以支持,但需要申请。
而抱歉的是截止目前我还没有得到具体的方法,因为我们还在它的申请流程中。。
具体申请流程请去OPPO开放平台找他们的人工客服获取申请方法。
6.4 VIVO
截止目前客服的解释为:不支持 & 没渠道申请
6.5 SAMSUNG
网上的方法难得的好用,但没有找到官方的回复,大家凑活用吧
private void setSAMSUNGIconBadgeNum(int count) throws Exception {
final Context context = App.getInstance().getBaseContext();
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", CappUtils.getLaunchIntentForPackage());
context.sendBroadcast(intent);
}
6.6 MEIZU
官方解释暂不支持
6.7 google
Android8.0开始支持了,但没有那么理想的效果,只能在图标上显示一个点;
长按这个点,能弹出一个小pop告诉你有多少消息。
private void setGoogleIconBadgeNum(int count) throws Exception {
final Context context = App.getInstance().getBaseContext();
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
throw new Exception(ERROR_LAUNCHER_NOT_SUPPORT_ + "Google");
}
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", CappUtils.getLaunchIntentForPackage()); // com.test. badge.MainActivity is your apk main activity
context.sendBroadcast(intent);
}
6.8 HTC
后续支持
6.9 Sony
后续支持
6.10 Nova
后续支持
6.11 LG
后续支持
7. 权限和注意事项
本库使用前请在清单文件中添加如下权限,切记切记
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果出现异常情况请优先检查权限是否全部添加
参考:https://blog.csdn.net/weixin_42976236/article/details/81704627
https://github.com/xuyisheng/ShortcutHelper
https://github.com/whytot/BadgeForAppIcon
https://blog.csdn.net/maoxian007/article/details/79848056
https://www.jianshu.com/p/0992ff9eeeb6