如何在三星手机上与徽章提供程序(BadgeProvider)进行接口交互,以便在应用图标上添加计数?

38

三星的TWLauncher允许应用在应用图标上创建徽章计数。

这完全没有文档记录!不管是哪里都没有提到它,只有少数应用在使用(例如Facebook,eBay)。

如何使用此功能将计数添加到您的应用程序图标中?

这与三星设备非常相关。 我不是在询问Android一般性的情况。我只是在询问如何为Samsung的Touchwhiz界面添加徽章,因为该界面目前支持徽章。 Android不支持。


我相信你的意思是“到处都没有记录”。除非你的意思是“没有地方有记录”。到处都没有记录?那是什么意思? - Samir
@sammyg 很好的观点,并且我已经进行了更改。基本上,我只是在说当我编写这篇文章时,互联网上没有关于如何与BadgeProvider进行接口的文档可用。 - Daniel Ochoa
可能是在Android中为应用程序图标添加徽章的方法?的重复问题。 - Shirish Herwade
@ShirishHerwade,你提供的链接没有给出答案。我已经回答了。 - Daniel Ochoa
@DanielOchoa,那么既然已经有一个问题存在,为什么你还要问另一个问题呢?这个标志是关于“重复问题”的;而不是关于重复答案或更好的答案。此外,您可以在那个问题下添加您的答案,然后自己关闭(删除)这个问题,帮助使stackoverflow变得更好。 - Shirish Herwade
@ShirishHerwade 因为当我搜索与三星徽章提供程序的接口时,没有任何问题弹出。该链接要求标记ANDROID。我的帖子不是关于Android的一般性。它是具体且仅针对三星的Touchwhiz界面。这是一个非常明确和有针对性的问题。该链接没有明确回答或询问三星设备的问题。这就是为什么我不会在那个链接上发布我的答案。我的问题/答案只适用于三星设备。 - Daniel Ochoa
7个回答

70

首先,您需要将以下权限添加到AndroidManifest.xml文件中。

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

列的结构如下:

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

为了从BadgeProvider查询所有结果,请按以下步骤进行:
// 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();
}

为了在您的应用程序图标上添加徽章计数,您需要:
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);

如果你想清除图标上的徽章计数

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


我已经创建了一个开源项目,您可以将其作为库导入以帮助处理此问题。它的许可证是Apache,所以请随意使用。

您可以从这里获取:https://github.com/shafty023/SamsungBadger


我会核实并回复您有关状态的情况。感谢您提供这个解决方案。 :) - Akarsh M
2
我为此创建了一个开源库。您可以在此处获取:https://github.com/shafty023/SamsungBadger - Daniel Ochoa
1
是的,我在三星设备上进行了测试,它完美地运行,不知道Facebook是如何在每个设备上实现这一点的。 - Skynet
1
它可以显示一个字符或字符串,比如星号“*”,而不是一个整数计数器吗? - Vikram Gupta
2
@DanielOchoa 我在使用代码时遇到了以下错误: Caused by: java.lang.SecurityException: Permission Denial: writing com.sec.android.provider.badge.BadgeProvider uri content://com.sec.badge/apps from pid=5325, uid=10242 requires com.sec.android.provider.badge.permission.WRITE, or grantUriPermission()请帮我解决这个问题。 - Shanto George
显示剩余20条评论

21

太棒了!最佳解决方案。 - NOlivNeto
这正是我一直在寻找的。太棒了!谢谢 - Sanjay D

17
将这些权限添加到清单中。
<!--for android badge-->
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS"/>

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

<!--for htc badge-->
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>

<!--for sony badge-->
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>

<!--for apex badge-->
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>

将这些包名称添加到您的类中:
    final String HOME_PACKAGE_SONY = "com.sonyericsson.home";
    final String HOME_PACKAGE_SAMSUNG = "com.sec.android.app.launcher";
    final String HOME_PACKAGE_LG = "com.lge.launcher2";
    final String HOME_PACKAGE_HTC = "com.htc.launcher";
    final String HOME_PACKAGE_ANDROID = "com.android.launcher";
    final String HOME_PACKAGE_APEX = "com.anddoes.launcher";
    final String HOME_PACKAGE_ADW = "org.adw.launcher";
    final String HOME_PACKAGE_ADW_EX = "org.adwfreak.launcher";
    final String HOME_PACKAGE_NOVA = "com.teslacoilsw.launcher";

用法:

  // just put your pachage and main activity class path
  String classPath = "ir.faasaa.resa.MainActivity";

           ContentValues cv = new ContentValues();
                    cv.put("package", context.getPackageName());
                    cv.put("class", classPath);
                    cv.put("badgecount", count);
           context.getContentResolver().insert(Uri.parse(HOME_PACKAGE_SAMSUNG), cv);

感谢ShortcutBadger的支持


8

在安卓系统中,我们没有像iOS那样的徽章式图标,但一些制造商支持在应用程序图标上显示徽章。

索尼和HTC提供支持。

在安卓系统中应用徽章式图标的示例

索尼和HTC支持将徽章添加到应用程序图标中。

对于索尼

<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />  

Intent intent= new Intent("com.sonyericsson.home.action.UPDATE_BADGE");

intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", Class Name);

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

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

intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", packageName);

sendBroadcast(intent);

针对HTC:

<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />  
 <uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" />  

Intent updateIntent = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
updateIntent.putExtra("packagename", packageName);
updateIntent.putExtra("count", number);
this.sendBroadcast(updateIntent);

Intent setNotificationIntent = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
ComponentName localComponentName = new ComponentName(packageName, className);
setNotificationIntent.putExtra("com.htc.launcher.extra.COMPONENT", localComponentName.flattenToShortString());
setNotificationIntent.putExtra("com.htc.launcher.extra.COUNT", number);
this.sendBroadcast(setNotificationIntent);

5

我使用这个类来适配三星和索尼设备(在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;
    }
}

非常感谢您!!这在Xamarin Forms/Android中运行得很好。 - hvaughan3

0

针对Android 8.0 Oreo用户-

对于那些在显示Samsung S8,S9或Pixel设备上的徽章计数遇到问题的用户,请注意ShortcutBadger库不支持其中的API>26,如issues中所述。在这里,您需要首先检查isBadgeCounterSupported是否支持 -

public boolean isBadgeCounterSupported() {
    // Workaround for bug in ShortcutBadger in version 1.1.19, registered as
    // https://github.com/leolin310148/ShortcutBadger/issues/266
    if (Build.MANUFACTURER.equalsIgnoreCase("Samsung") && Build.VERSION.SDK_INT >= 26) {
        Log.d("LOG_TAG", "Launcher icon badge (ShortcutBadger) is not supported on Samsung devices running Android 8 (or newer).");
        return false;
    }

    return ShortcutBadger.isBadgeCounterSupported(context);
}

唯一的方法是从通知中应用徽章。至于如何从您的通知中应用徽章,请参阅Android文档,并注意“设置自定义通知计数”的部分。

Notification notification = new NotificationCompat.Builder(MainActivity.this, "my_channel_01")
    .setContentTitle("New Messages")
    .setContentText("You've received 3 new messages.")
    .setSmallIcon(R.drawable.ic_notify_status)
    .setNumber(messageCount) //this badge count
    .build();

enter image description here

如需了解Android 8.0中的通知,请参阅this answer


问题在于,仍有几个应用程序能够在图标上显示红色徽章计数,因此这不是一个可行的解决方案。我们需要弄清楚这些应用程序是如何设置徽章计数的。 - strangetimes
请问有关于应用程序的参考资料吗? - karanatwal.github.io
Twitter在三星S8上。我想出它可能唯一的方法就像你上面描述的那样,但不幸的是需要发布通知。过去,您可以单独设置徽章计数,这是不错的。 - strangetimes
是的,随着时间的推移,现在从Oreo开始,点徽章在安卓系统中得到了官方支持。希望将来尽快实现数字徽章。 https://medium.com/cr8resume/notification-in-android-8-0-oreo-implementing-notification-channels-d65b0f81ca50 - karanatwal.github.io

0

对于Xperia设备,您可以使用另一种工具

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



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

以下是更多细节。

http://www.marcusforsberg.net/blog/android-notification-badge-app-icon-sony/


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