如何在Sony Xperia设备的应用图标上添加通知徽章/计数?

34

使用Sony的Xperia Home,某些应用程序可以在应用程序图标上显示计数气泡或徽章。Facebook和Facebook Messenger都可以这样做,内置的电子邮件应用程序也可以。

对于三星的启动器已经解决了此问题,但我没有找到任何有关如何在Sony的启动器上实现的文档。

怎么做呢?


我因为声望不够,在8小时内无法回答自己的问题,所以无法将此作为答案发布。但是,这里有一个关于如何实现的指南:http://marcusforsberg.net/blog/android-how-to-add-a-notification-badge-to-app-icon-on-sony-xperia-devices/。我会在今天稍后发布并接受它作为答案,当我被允许时。 - Marcus
我找到了关于viewBadge的答案。https://github.com/jgilfelt/android-viewbadger 你可以仔细研究一下,看看它是否适用于你的情况。如果有人遇到问题,请告诉我。 - Developer
4个回答

49

在看过了Daniel Ochoa在三星启动器中使用BadgeProvider来处理标记的解决方案之后,我开始尝试为Sony的Xperia Home做同样的事情。这个回答是直接从我的博客中获取的。

我是如何找到方法的 - 对于任何感兴趣的人

我偶然发现了Sony的AppXplore,并用它来检查Facebook应用程序的权限。 Facebook应用程序请求以下权限,这是在Sony设备上显示徽章的关键:

com.sonyericsson.home.permission.BROADCAST_BADGE

接下来,我查看了所有可用的内容提供者,但没有找到与应用程序图标徽章有关的内容。我运行了此答案中的命令来获取系统转储文件,并使用Notepad++搜索“badge”。我找到了这个:

com.sonyericsson.home.action.UPDATE_BADGE: 41be9a90 com.sonyericsson.home/.BadgeService$BadgeReceiver filter 41be9858

所以,在Sony上使用BroadcastReciever来处理它,而不是Samsung的Content Provider。因此,我创建了一个自己的虚拟BroadcastReciever,监听动作com.sonyericsson.home.action.UPDATE_BADGE,并找到了Facebook的BadgeService传递的extra参数。 为此,我还需要一个权限,但在转储文件中很容易找到:

com.sonyericsson.home.permission.RECEIVE_BADGE

由Facebook、电子邮件应用程序等发送的extras是:

  • com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME - 您应用的主要活动名称android.intent.action.MAIN。这样启动器就知道要显示徽章的图标。
  • com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE - 一个布尔值,表示我们是否要显示徽章(当然要!)
  • com.sonyericsson.home.intent.extra.badge.MESSAGE - 一个字符串(不是整数-我花了一段时间才意识到...),其中包含要显示的数字。
  • com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME - 应用程序包的名称。

如何在Sony Xperia设备上显示应用程序launcher图标上的徽章

因此,在启动器中显示应用程序图标上的徽章非常简单。在我看来,这比对于三星的启动器要简单得多。 以下是一份逐步指南(而且不长!):

  1. 在您的清单文件中声明com.sonyericsson.home.permission.BROADCAST_BADGE权限:

  2. BadgeReceiver广播一个Intent

  3. Intent intent = new Intent();
    
    intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", "com.yourdomain.yourapp.MainActivity");
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", "99");
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", "com.yourdomain.yourapp");
    
    sendBroadcast(intent);
    
  4. 完成。一旦广播此Intent,启动器应在您的应用程序图标上显示徽章。

  5. 要再次删除徽章,只需发送一个新的广播,这次将SHOW_MESSAGE设置为false:

  6. intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", false);
    

好知道

信息是一个字符串!

由于MESSAGE是一个String,因此您实际上可以向徽章添加单词:

intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", "Testing");

但我不会这样做,因为它看起来很奇怪。

您可以访问所有应用程序!

BROADCAST_BADGE 权限不仅可让您访问自己的应用程序图标,还包括所有其他应用程序的图标。例如,以下是如何设置 Facebook 徽章的方法:

Intent intent = new Intent();
intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", "com.facebook.katana.LoginActivity");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", "99");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", "com.facebook.katana");

sendBroadcast(intent);
我希望这对某个人有所帮助! :)

感谢分享! - Damien R.
由于这是一个广播接收器,我猜想没有办法查询您当前的徽章记录?此外,Sony是否区分UPDATE_BADGE和CREATE_BADGE?即使您以前从未创建过徽章记录,您是否总是发送UPDATE_BADGE? - Daniel Ochoa
据我所知,UPDATE_BADGE 总是被使用,而不是 CREATE_BADGE。是的,即使没有先前的徽章,也会使用 UPDATE_BADGE。不,我认为您无法查看徽章当前的内容 - 您必须手动跟踪它。 :) - Marcus
关于此事的更新,第三方启动器Apex也支持徽章,类似于索尼的启动器:http://forum.xda-developers.com/showthread.php?t=1930365 - Marcus
@Marcus 这段代码只能用于索尼Xperia设备吗? - Shivam Kumar

30

我在三星、索尼和HTC设备上使用这个类(还可以在https://gist.github.com/Tadas44/cdae2f5995f21bf1c27f找到)。别忘了在 AndroidManifest.xml 中添加 <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />

public class BadgeUtils {


    public static void setBadge(Context context, int count) {
        setBadgeSamsung(context, count);
        setBadgeSony(context, count);
    }

    public static void clearBadge(Context context) {
        setBadgeSamsung(context, 0);
        clearBadgeSony(context);
    }


    private static void setBadgeSamsung(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);
    }

    private static void setBadgeSony(Context context, int count) {
        String launcherClassName = getLauncherClassName(context);
        if (launcherClassName == null) {
            return;
        }

        Intent intent = new Intent();
        intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(count));
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());

        context.sendBroadcast(intent);
    }


    private static void clearBadgeSony(Context context) {
        String launcherClassName = getLauncherClassName(context);
        if (launcherClassName == null) {
            return;
        }

        Intent intent = new Intent();
        intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", false);
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(0));
        intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());

        context.sendBroadcast(intent);
    }

    private static String getLauncherClassName(Context context) {

        PackageManager pm = context.getPackageManager();

        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);

        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
        for (ResolveInfo resolveInfo : resolveInfos) {
            String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
            if (pkgName.equalsIgnoreCase(context.getPackageName())) {
                String className = resolveInfo.activityInfo.name;
                return className;
            }
        }
        return null;
    }
}

1
大家好,有人知道三星和索尼设备上徽章更新的最小SDK要求是多少吗?先谢谢了。 - Jan
干得好!希望支持更多的手机,如小米、宏碁、HTC和摩托罗拉。 - Zhang Zhan

0

0

嘿,我已经解决了这个问题,并想要发布一个答案,但是我没有达到10声望无法这样做...哎呀。:P稍后会在评论中发布答案链接,并在允许的8小时后将其作为答案发布。 - Marcus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接