如何在应用启动器图标中显示通知计数[重复]

Posted

技术标签:

【中文标题】如何在应用启动器图标中显示通知计数[重复]【英文标题】:How to display count of notifications in app launcher icon [duplicate] 【发布时间】:2013-07-08 01:37:54 【问题描述】:

三星 Galaxy Note 2 安卓版本 4.1.2

我知道之前有人问过这个问题,无法回复

如何在应用程序启动器图标上显示气球计数器 安卓

尽管如此,昨天我更新了 Facebook 应用程序,它开始显示未读消息的私人消息计数器。 facebook 应用程序为什么可以,而我的应用程序不能这样做?

三星 Galaxy Note 2 安卓版本 4.1.2

【问题讨论】:

这是在您的应用列表中还是在您的主屏幕上? 应用列表不是主屏幕 请大家睁大眼睛。这是 TouchWiz 而不是 Vanilla android。请提供在原厂 Android 主屏幕(例如 Nexus 系列设备之一)上看到这些徽章的证据。 ***.com/questions/7203541/…***.com/questions/6381157/… 安卓版本 4.1.2 【参考方案1】:

Android(“vanilla”android 没有自定义启动器和触摸界面)不允许更改应用程序图标,因为它在程序编译后被紧紧地密封在 .apk 中。无法使用标准 API 以编程方式将其更改为“可绘制”。您可以通过使用小部件而不是图标来实现您的目标。小部件是可定制的。请阅读此:http://www.cnet.com/8301-19736_1-10278814-251.html 和此http://developer.android.com/guide/topics/appwidgets/index.html。 也看这里:https://github.com/jgilfelt/android-viewbadger。它可以帮助你。

至于徽章编号。正如我之前所说 - 没有标准的方法可以做到这一点。但是我们都知道 Android 是一个开放的操作系统,我们可以用它做任何我们想做的事情,所以添加徽章编号的唯一方法是使用一些 3-rd 方应用程序或自定义启动器,或者前端触摸界面:三星 TouchWiz 或索尼 Xperia 的界面。其他答案使用此功能,您可以在 *** 上搜索此功能,例如here。但我会再重复一遍:没有标准 API 用于此,我想说这是一种糟糕的做法。应用程序的图标通知徽章是一种 ios 模式,无论如何都不应该在 Android 应用程序中使用。在 Andrioid 中有一个用于这些目的的状态栏通知:http://developer.android.com/guide/topics/ui/notifiers/notifications.html 因此,如果 Facebook 或其他人使用它 - 这不是我们应该考虑的常见模式或趋势。但是,如果您仍然坚持并且不想使用主屏幕小部件,那么请看这里:

How does Facebook add badge numbers on app icon in Android?

如您所见,这不是真正的 Facebook 应用,它是 TouchWiz。在 vanilla android 中,这可以通过 Nova Launcher http://forums.androidcentral.com/android-applications/199709-how-guide-global-badge-notifications.html 来实现 因此,如果您会在某处看到图标徽章,请确保它是 3 方启动器或触摸界面(前端包装器)。 Google 可能会在某个时候将此功能添加到标准 Android API 中。

【讨论】:

这不是应用程序标签中的小部件 小部件是可定制的,你是对的。使用小部件而不是图标。好主意。谢谢。 @user2443241 请参考这个问题,尤其是 CommonsWare 的答案。 ***.com/questions/1103027/… 如果您甚至以某种丑陋和肮脏的方式(例如更改清单)以编程方式更新您的图标,那么您将无法签署您的应用程序。请查看我为回答所做的编辑。 看看我刚刚添加的图片 @user2443241 请告诉我您使用的 Android 设备。我认为 Facebook 使用了某种 TouchWiz API techcrunch.com/2009/08/17/… 但如果你有没有 Nova 的普通 android 设备,那么我认为 Facebook 使用了某种肮脏的魔法......【参考方案2】:

它适用于三星touchwiz启动器

public static void setBadge(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);


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

【讨论】:

你能告诉我如何清除徽章吗? @DixitPatel 这很简单。只需“setBadge(context, 0)” 答案简单易懂总是好的!1 Cheers ChangUZ 它可以显示一个字符或字符串,比如一个星号'*',而不是一个整数计数器? 好工作,工作完美,SET:正数,UNSET:负数或 0【参考方案3】:

ShortcutBadger 是一个库,它在设备品牌和当前启动器上添加了一个抽象层,并提供了很好的结果。适用于 LG、索尼、三星、HTC 和其他自定义启动器。

它甚至可以在纯 Android 设备桌面上显示徽章计数。

在应用程序图标中更新徽章计数就像调用一样简单:

int badgeCount = 1;
ShortcutBadger.applyCount(context, badgeCount);

它包含一个演示应用程序,可让您测试其行为。

【讨论】:

谢谢,它运行良好,但我想知道 Line、What's app、Solmail 等应用程序如何在没有这些权限的情况下使用徽章。有什么想法吗? @Virusman,我认为这种权限不会显示给用户。您可以通过从 apk 安装示例应用程序来测试它。但是,包含所需的权限应该不是问题。 是的,我在安装过程中只看到了三星的权限,但是我反编译了 Line 应用程序,并没有看到任何徽章权限。 Nexus(纯 Android)设备将仅在桌面图标上显示徽章计数 此库在 Android 7.0 及更高版本中不起作用。我用 nexus 5x 和 nexus 6 检查它。【参考方案4】:

我已经弄清楚索尼设备是如何做到这一点的。

我已经在博客上写了 here。我还发布了一个关于此here 的单独 SO 问题。


Sony 设备使用名为 BadgeReciever 的类。

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

    Intent 广播到BadgeReceiver

    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 后,启动器应在您的应用程序图标上显示一个徽章。

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

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

我已排除有关如何找到此问题的详细信息以保持答案简短,但所有内容都可以在博客中找到。对某人来说可能是一本有趣的书。

【讨论】:

嗨,马库斯,我应该为 Moto cPlus 移动型号尝试上述相同的操作吗?它是专门用于特定设备还是适用于所有 android 手机 @harikrishnan 正如答案中所述,这仅适用于索尼手机。但是,您可以查看上面的 AlexGutis 响应,了解可以为多种型号解决此问题的库 - 或许也适用于 Moto 手机。 感谢马库斯的回复。我已经尝试过 AlexGutis ShortcutBadger 的答案。但是,它不适用于我的 moto 模型。 您博客的网址是一个损坏的链接!能更新一下链接吗?【参考方案5】:

这是在通知启动器图标上显示徽章的示例和最佳方式。

在您的应用程序中添加此类

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;
    



==> MyGcmListenerService.java 收到通知时使用 BadgeUtils 类。

public class MyGcmListenerService extends GcmListenerService  

    private static final String TAG = "MyGcmListenerService"; 
    @Override
    public void onMessageReceived(String from, Bundle data) 

            String message = data.getString("Msg");
            String Type = data.getString("Type"); 
            Intent intent = new Intent(this, SplashActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                    PendingIntent.FLAG_ONE_SHOT);

            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

            NotificationCompat.BigTextStyle bigTextStyle= new NotificationCompat.BigTextStyle();

            bigTextStyle .setBigContentTitle(getString(R.string.app_name))
                    .bigText(message);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setSmallIcon(getNotificationIcon())
                    .setContentTitle(getString(R.string.app_name))
                    .setContentText(message)
                    .setStyle(bigTextStyle) 
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

            int color = getResources().getColor(R.color.appColor);
            notificationBuilder.setColor(color);
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


            int unOpenCount=AppUtill.getPreferenceInt("NOTICOUNT",this);
            unOpenCount=unOpenCount+1;

            AppUtill.savePreferenceLong("NOTICOUNT",unOpenCount,this);  
            notificationManager.notify(unOpenCount /* ID of notification */, notificationBuilder.build()); 

// This is for bladge on home icon          
        BadgeUtils.setBadge(MyGcmListenerService.this,(int)unOpenCount);

    


    private int getNotificationIcon() 
        boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
        return useWhiteIcon ? R.drawable.notification_small_icon : R.drawable.icon_launcher;
    

并从偏好中清除通知以及徽章计数

 public class SplashActivity extends AppCompatActivity  
                @Override
                protected void onCreate(Bundle savedInstanceState) 
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_splash);

                    AppUtill.savePreferenceLong("NOTICOUNT",0,this);
                    BadgeUtils.clearBadge(this);
            
    
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />

【讨论】:

它似乎只适用于索尼手机 这也适用于索尼、HTC 和三星设备。

以上是关于如何在应用启动器图标中显示通知计数[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Android 应用程序图标中的通知计数徽章

如何在我的 Android 应用程序中的启动器图标上显示徽章计数?

如何在 Facebook 等应用程序图标上显示通知计数?

如何在 Android 主屏幕上的我的应用程序图标上显示通知计数

Android 未读消息计数显示在应用程序图标上

重新安装应用后 Xamarin.iOS 应用图标上的徽章计数不正确