【问题标题】:How to interface with the BadgeProvider on Samsung phones to add a count to the app icon?如何与三星手机上的 BadgeProvider 交互以向应用程序图标添加计数?
【发布时间】:2013-11-22 03:25:50
【问题描述】:

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

这完全没有记录! 任何地方都没有提到它,只有少数应用程序在使用它(例如 Facebook、eBay)。

您如何使用此功能为您的应用图标添加计数?

这是非常特定于三星设备的。我不是在问一般的Android。我只是在问三星的 Touchwhiz 界面,它目前允许标记。安卓没有。

【问题讨论】:

  • 我相信您的意思是“无处不在”。除非您的意思是“无处记录”。无证任何地方???这是什么意思?
  • @sammyg 好点,做出了改变。基本上只是说当我写这篇文章时,互联网上没有关于如何与 BadgeProvider 交互的文档。
  • @ShirishHerwade 您引用的链接没有给出答案。我做到了。
  • @DanielOchoa 那么为什么在已经有一个存在的情况下首先问另一个问题。这个标志是关于“重复问题”的;不是重复答案或更好的答案。您也可以在该问题下添加您的答案,然后自己关闭(删除)该问题并帮助使 stackoverflow 成为一个更好的地方

标签: android badge samsung-touchwiz


【解决方案1】:

首先,您需要将以下权限添加到您的 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

【讨论】:

  • 能否请您详细说明...?
  • 我为此创建了一个开源库。你可以在这里得到它:github.com/shafty023/SamsungBadger
  • 是的,我在三星设备上进行了测试,它运行良好,不知道 Facebook 是如何在每台设备上做到这一点的。
  • 它可以显示一个字符或字符串,比如一个星号'*',而不是一个整数计数器?
  • @DanielOchoa 我在使用代码时收到此错误原因:java.lang.SecurityException:权限被拒绝:编写 com.sec.android.provider.badge.BadgeProvider uri content://com。 pid=5325, uid=10242 的 sec.badge/apps 需要 com.sec.android.provider.badge.permission.WRITE 或 grantUriPermission() 请帮我解决这个问题
【解决方案2】:

还有另一个很酷的支持不同设备的开源库: https://github.com/leolin310148/ShortcutBadger/

【讨论】:

  • 太棒了!最佳解决方案。
  • 这正是我正在寻找的。惊人的!!谢谢
【解决方案3】:

将这些权限添加到清单

<!--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

【讨论】:

    【解决方案4】:

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

    支持索尼和 HTC。

    Example for badge style icon on app in android

    Sony 和 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)。不要忘记将&lt;uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" /&gt; 添加到AndroidManifest.xml

      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 中也能很好地工作。
      【解决方案6】:

      还有另一种工具可用于 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/

      【讨论】:

        【解决方案7】:

        适用于 Android 8.0 Oreo 用户-

        对于那些在显示带有 Oreo 的 Samsung S8、S9 或 Pixel 设备的徽章计数时遇到问题的用户,请注意 ShortcutBadger Library 不支持 API&gt;26 for Samsung 在此处报告在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 documentation,并注意“设置自定义通知计数”部分。

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

        有关 Android 8.0 中通知的更多信息,请参阅this answer

        【讨论】:

        • 问题是,仍有一些应用程序能够在图标上显示红色徽章计数,因此这不是一个可行的解决方案。我们需要弄清楚这些应用程序是如何设置徽章数量的。
        • 请参考应用程序吗?
        • 三星 S8 上的 Twitter。我发现它这样做的唯一方法可能就像您在上面描述的那样,但不幸的是需要在旁边发布通知。过去你可以单独设置徽章数量,这很好。
        • 是的,随着时间的推移发生了一些变化,现在来自 Oreo 的圆点徽章在 android 中得到正式支持。 medium.com/cr8resume/…希望以后能尽快拿到数字徽章
        猜你喜欢
        • 1970-01-01
        • 2019-10-02
        • 1970-01-01
        • 2022-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多