Android 桌面角标的适配

1,573 阅读5分钟

一个本不该存在在 android 系统中的功能。

为什么这么说呢?google从来没有在android系统中设计这个功能。本人也非常不喜欢这么做。。。 原本就有通知栏提醒的情况下,何必重复添加一个提醒。尤其对强迫症患者来说,一些无关紧要的提醒
却让桌面图标上多了一个数字,而且根本不知道这个数字想告诉你什么,简直不能忍。直接看顶部的通
知多好啊!
既然一些(好吧,大部分)厂家,非要效仿ios,那肯定会有用户提出这种需求了。但是要怎么做呢?
google的文档上坑定是没有了。只能去各个公司的开发着平台上找了。。。
Ps: 今年的开发者大会上还有人问了这个问题。回答是:android一直都在变,他也不知道将来会是什
么样子。

ShortcutBadger:

support-devices

先推荐一个 GitHub Library: ShortcutBadger 如上图,它集成了很多 launchers 的角标提醒。
但是很不幸的是,图很美。现实并不是,所以如果想粗略的实现该功能,推荐使用上库。

不得不说,整理这个的人还挺多的,又搜到一个:https://github.com/l123456789jy/Lazy/blob/master/lazylibrary/src/main/java/com/github/lazylibrary/util/BadgeUtil.java

这些都差不多,看着用吧。

不支持的厂商

魅族,中兴,酷派...
必须点赞啊,不跟风。

华为

华为的文档很好找,说明也很清楚,还有Demo,真是服务周到。 文档地址:http://developer.huawei.com/consumer/cn/wiki/index.php?title=%E5%8D%8E%E4%B8%BA%E6%A1%8C%E9%9D%A2%E8%A7%92%E6%A0%87SDK%E4%B8%8B%E8%BD%BD 使用方式 manifest 中添加权限。

<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
<uses-permission android:name="com.huawei.permission.sec.MDM"/>

在代码中添加方法:

//检测EMUI版本是否支持
public void checkIsSupportedByVersion(){
    try {
      PackageManager manager = getPackageManager();
      PackageInfo info = manager.getPackageInfo("com.huawei.android.launcher", 0);
      if(info.versionCode>=63029){
        isSupportedBade = true;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

//控制显示的个数
private void handleBadge(int num){
  if(!isSupportedBade){
    Log.i("badgedemo", "not supported badge!");
    return;
  }
  try{
    Bundle bunlde =new Bundle();
    bunlde.putString("package", "com.example.badgedemo");
    bunlde.putString("class", "com.example.badgedemo.MainActivity");
    bunlde.putInt("badgenumber",num);
    ContentResolver t=this.getContentResolver();
    Bundle result=t.call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_launcher_badge", "", bunlde);
  }catch(Exception e){
    e.printStackTrace();
  }
}

小米

文档地址
小米还算良心,文档比较好找。

基本介绍

默认的情况
当app 向通知栏发送了一条通知 (通知不带进度条并且用户可以删除的),那么桌面app icon角标就会显示1.
此时app显示的角标数是和通知栏里app发送的通知数对应的,即向通知栏发送了多少通知就会显示多少角标。
通知可以定义角标数
例如 有5封未读邮件,通知栏里只会显示一条通知,但是想让角标显示5. 可以在发通知时加个标示。 实现代码

第三方app需要用反射来调用,参考代码:


NotificationManager mNotificationManager = (NotificationManager) this

.getSystemService(Context.NOTIFICATION_SERVICE);



Notification.Builder builder = new Notification.Builder(this)

.setContentTitle(“title”).setContentText(“text”).setSmallIcon(R.drawable.icon);

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, mCount);

} catch (Exception e) {

e.printStackTrace();

}

mNotificationManager.notify(0,notification);

三星

官方只找到了应用商店上传应用的一些文档和主题文档
算了,高手在民间吧。 额,我又犯了一个错误。我先用的是google中文的搜索。。。

中文 英文
chinese.png
english.png

先看看中文搜索结果

中文找到了:找到了简书这篇Badge分析&如何逼死处女座 以下方法转自那篇简书文章:

方法一

通过三星Launcher自己的广播,来给应用添加角标:

/**
 * 设置三星的Badge
 *
 * @param context context
 * @param count   count
 */
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);
}

此方法不需要任何权限,只需要知道App的包名和类名。因此,你当然可以在程序里面给其它任意一个App设置任意数量的角标,
而且没有任何提示,是的,很流氓,谁说不是呢,当然别说是我告诉你的,你就所你是百度的。例如:

intent.putExtra("badge_count_package_name", "com.tencent.mobileqq"); intent.putExtra("badge_count_class_name", "com.tencent.mobileqq.activity.SplashActivity"); 将包名和类名用QQ的替换下,然后你就可以随心所欲、为所欲为了。

方法二

https://github.com/shafty023/SamsungBadger
三年前更新的,不知道还能用不。。。

再看看英文吧

点开第一个stackoverflow
点赞最多的答案: First you'll need to add the following permissions to your AndroidManifest.xml file.

<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />

The column structure is as follows:

(integer) _id, (text) package, (text) class, (integer) badgecount, (blob) icon, (???) extraData

In order to query ALL results from the BadgeProvider do the following:

// This is the content uri for the BadgeProvider
Uri uri = Uri.parse("content://com.sec.badge/apps");

Cursor c = getContentResolver().query(uri, null, null, null, null);

// This indicates the provider doesn't exist and you probably aren't running
// on a Samsung phone running TWLauncher. This has to be outside of try/finally block
if (c == null) {
    return;
}

try {
    if (!c.moveToFirst()) {
        // No results. Nothing to query
        return;
    }

    c.moveToPosition(-1);
    while (c.moveToNext()) {
        String pkg = c.getString(1);
        String clazz = c.getString(2);
        int badgeCount = c.getInt(3);
        Log.d("BadgeTest", "package: " + pkg + ", class: " + clazz + ", count: " + String.valueOf(cnt));
    }
} finally {
    c.close();
}

In order to add a badge count to your application icon

ContentValues cv = new ContentValues();
cv.put("package", getPackageName());
// Name of your activity declared in the manifest as android.intent.action.MAIN.
// Must be fully qualified name as shown below
cv.put("class", "com.example.badge.activity.Test");
cv.put("badgecount", 1); // integer count you want to display

// Execute insert
getContentResolver().insert(Uri.parse("content://com.sec.badge/apps"), cv);

If you want to clear the badge count on your icon

ContentValues cv = new ContentValues();
cv.put("badgecount", 0);
getContentResolver().update(Uri.parse("content://com.sec.badge/apps"), cv, "package=?", new String[] {getPackageName()});  

NEW
I have created an open source project that you can import as a library to assist with this. It's licensed as Apache so feel free to use it as you please.
You can get it from here: https://github.com/shafty023/SamsungBadger

额,这不就是那个三年前停止更新的github的项目吗。。。。崩溃!

点赞第二多的:
There is another cool open source library that support different devices:
https://github.com/leolin310148/ShortcutBadger/

好吧,都是见过的。

LG

据说和 samsung 一样。

sony

果然大厂 google 一下就找到了。
地址:https://developer.sony.com/2016/06/23/xperia-home-badge-api-now-publicly-available/

oppo

网上根本找不到相关文档。 这种肆意模仿 apple 的公司自然有这个功能了。然而文档并没有,而且网上几乎搜不到。。。 github:ShortcutBadger说有支持。没有测试机,没法测试啊。。。而且根本不知道他们什么时候开始支持的。
最近在百度云测上测了一下,github:ShortcutBadger 这个项目可以。

vivo

网上根本找不到相关文档。 这篇说可以,不知道行不行。没有测试机。 http://www.lai18.com/content/9532859.html
这一篇看起来比较靠谱: http://blog.csdn.net/dbs1215/article/details/53054073

金立

网上根本找不到相关文档。

以上三家公司的开发者平台,结构几乎一模一样,真是佩服!