200

samsung galaxy note 2 android version 4.1.2

I know that this question was asked before and the reply was not possible

How to display balloon counter over application launcher icon on android

Nevertheless yesterday I updated the facebook app and it started to show a counter of unread messages private messages. How come facebook app can and I cant do so for my app?

facebook icon

enter image description here

samsung galaxy note 2 android version 4.1.2

Waqleh
  • 8,454
  • 8
  • 61
  • 91

5 Answers5

127

Android ("vanilla" android without custom launchers and touch interfaces) does not allow changing of the application icon, because it is sealed in the .apk tightly once the program is compiled. There is no way to change it to a 'drawable' programmatically using standard APIs. You may achieve your goal by using a widget instead of an icon. Widgets are customisable. Please read this :http://www.cnet.com/8301-19736_1-10278814-251.html and this http://developer.android.com/guide/topics/appwidgets/index.html. Also look here: https://github.com/jgilfelt/android-viewbadger. It can help you.

As for badge numbers. As I said before - there is no standard way for doing this. But we all know that Android is an open operating system and we can do everything we want with it, so the only way to add a badge number - is either to use some 3-rd party apps or custom launchers, or front-end touch interfaces: Samsung TouchWiz or Sony Xperia's interface. Other answers use this capabilities and you can search for this on stackoverflow, e.g. here. But I will repeat one more time: there is no standard API for this and I want to say it is a bad practice. App's icon notification badge is an iOS pattern and it should not be used in Android apps anyway. In Andrioid there is a status bar notifications for these purposes:http://developer.android.com/guide/topics/ui/notifiers/notifications.html So, if Facebook or someone other use this - it is not a common pattern or trend we should consider. But if you insist anyway and don't want to use home screen widgets then look here, please:

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

As you see this is not an actual Facebook app it's TouchWiz. In vanilla android this can be achieved with Nova Launcher http://forums.androidcentral.com/android-applications/199709-how-guide-global-badge-notifications.html So if you will see icon badges somewhere, be sure it is either a 3-rd party launcher or touch interface (frontend wrapper). May be sometime Google will add this capability to the standard Android API.

Community
  • 1
  • 1
Oleksandr Karaberov
  • 12,223
  • 10
  • 39
  • 68
  • this is not a widget this is in the apps tab – Waqleh Jul 10 '13 at 08:19
  • 1
    Widgets are customisable you are right. Use widget instead of an icon. Good idea. Thank you. – TeachMeJava Jul 10 '13 at 08:21
  • @user2443241 Please refer this question especially CommonsWare answer. http://stackoverflow.com/questions/1103027/how-to-change-an-application-icon-programmatically-in-android If you even in some ugly and dirty way (like changing manifest) will update your icon programmatically then you will not be able to sign your app.And please look at edits I did for my answer. – Oleksandr Karaberov Jul 10 '13 at 08:26
  • take a look at the image i just added – Waqleh Jul 10 '13 at 09:12
  • @user2443241 Please told me what Android device you use. I think Facebook use some kind of TouchWiz API http://techcrunch.com/2009/08/17/samsung-opens-up-touchwiz-widget-development/ But if you have vanilla android device without Nova then i think Facebook use some kind of dirty magic for this... – Oleksandr Karaberov Jul 10 '13 at 09:20
  • samsung galaxy note 2 android version 4.1.2 – Waqleh Jul 10 '13 at 09:26
  • @user2443241 Then please look here http://en.wikipedia.org/wiki/TouchWiz I'm sick of explaining and giving proof links that this badge feature not pure Android but TouchWiz layer. On my Nexus 4 which is stock Android smartphone my Facebook app didn't show any badges. I give you a detailed explanations. I don't want to explain something more.Good luck – Oleksandr Karaberov Jul 10 '13 at 09:31
  • ok so this will work on some samsung devices, cool. Ok thank, i think it is worth doing since samsung is wide spread. :) – Waqleh Jul 10 '13 at 09:36
  • @Till now TouchWiz has a proprietary API.But Samsung announce that soon they will make it public: http://developer.samsung.com/android Refer also this useful answer: http://stackoverflow.com/questions/6864184/how-do-i-set-up-htc-sense-and-samsung-touchwiz-app-icon-badges If I help in some way you can accept my answer other people will see it. – Oleksandr Karaberov Jul 10 '13 at 09:39
94

It works in samsung touchwiz launcher

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;
}
ChangUZ
  • 5,152
  • 10
  • 42
  • 64
79

ShortcutBadger is a library that adds an abstraction layer over the device brand and current launcher and offers a great result. Works with LG, Sony, Samsung, HTC and other custom Launchers.

It even has a way to display Badge Count in Pure Android devices desktop.

Updating the Badge Count in the application icon is as easy as calling:

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

It includes a demo application that allows you to test its behavior.

AlexGuti
  • 2,553
  • 1
  • 22
  • 26
  • Thanks, It's work well, But I wonder how apps like Line, What's app, Solmail etc. uses badge without those lots of permissions. Any Idea? – Saeed.re Nov 06 '14 at 15:15
  • @Virusman, i think that this kind of permissions are not displayed to the user. You can test it by installing the Sample App from the apk. However, it should not be a problem to include permissions that are needed. – AlexGuti Nov 07 '14 at 13:25
  • Yes I only saw samsung's permissions among all of them during installation, But I decompiled Line app and didn't see any of badge permissions there. – Saeed.re Nov 07 '14 at 17:09
  • @AlexGuti Thanks for your efficient answer. ShortcutBadger is working fine on Sony and Saamsung but how to use with Nexus device. – Shoeb Ahmed Siddique Jan 06 '15 at 10:18
  • 2
    The Nexus (pure Android) devices will display badge count only on icons in desktop – AlexGuti Jan 08 '15 at 15:52
  • It seems not support Huawei , cause I have tested Huawei P7. – Veer Aug 24 '16 at 09:57
  • @Leo.Han, in the docs it's said that Huawei is supported for version 1.1.7+ – AlexGuti Aug 24 '16 at 12:02
  • @AlexGuti, yeah, I saw the docs. I used v1.1.8, but it still didn't work. I checked out that Huawei needs a certificate which needs to be applied in Huawei Official website, and then your App can use the badge API. – Veer Aug 25 '16 at 01:13
  • For using this, we need to add persmission for each device seprately and for sony devices suppose your using it without persmission, it will crash even you use try catch around. for other devices like Huawei honor holly,its not crashing – Sahil Jan 12 '17 at 13:30
  • 2
    this library do not work in Android 7.0 and above. I check it with nexus 5x and nexus 6. – Mahdi Apr 16 '17 at 07:20
  • @Kenji, i just tried the demo app on a Galaxy S7 with Android 7 and works perfect. I tried it previously on Nexus devices with Android 4 and only worked for icons on desktop, not app launcher – AlexGuti Apr 18 '17 at 11:12
  • Here, how to get badgeCount when app in background and push notification came? – Avinash May 24 '17 at 08:50
  • @Avi If you are implementing FCM then you will have to extend a `GcmReceiver` for more have a look at https://medium.com/@deividi/a-good-way-to-handle-incoming-notifications-in-android-dc64c29041a5 – Faisal Naseer Aug 04 '17 at 12:49
  • Not working when the app is the background or killed – androholic Oct 09 '18 at 05:19
12

I have figured out how this is done for Sony devices.

I've blogged about it here. I've also posted a seperate SO question about this here.


Sony devices use a class named BadgeReciever.

  1. Declare the com.sonyericsson.home.permission.BROADCAST_BADGE permission in your manifest file:

  2. Broadcast an Intent to the 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);
    
  3. Done. Once this Intent is broadcast the launcher should show a badge on your application icon.

  4. To remove the badge again, simply send a new broadcast, this time with SHOW_MESSAGE set to false:

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

I've excluded details on how I found this to keep the answer short, but it's all available in the blog. Might be an interesting read for someone.

Community
  • 1
  • 1
Marcus
  • 1,623
  • 1
  • 16
  • 22
  • Hi Marcus, shall i try the above same for Moto cPlus mobile models?. is it for specifically for particular devices or common for all android mobiles – harikrishnan Dec 18 '17 at 11:45
  • @harikrishnan As stated in the answer, this is only for Sony phones. However, you can check out AlexGutis response above for a library that solves this for several models - perhaps also for Moto phones. – Marcus Dec 18 '17 at 11:52
  • thank you for reply Marcus. I have tried already for AlexGutis ShortcutBadger answer. but, its not working for my moto model. – harikrishnan Dec 19 '17 at 12:25
  • The url to your blog is a broken link! Can you please update the link ? – Abhishek Ghosh Jul 02 '18 at 16:02
10

This is sample and best way for showing badge on notification launcher icon.

Add This Class in your application

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 Use BadgeUtils class when notification comes.

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

And clear notification from preference and also with badge count

 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" />
Jaydeep purohit
  • 1,314
  • 16
  • 19