Showing Badge or Count in Android App Icon

Showing a badge or count in an Android application is the capability that is supported by launcher application. Android launcher by default does not support the use of badges or counts while they list the application icons. In some android phones like Galaxy S3 etc, we can see that applications like facebook and email client is capable of displaying the count on their application icon, its actually with the help of the samsung launcher (You can google to get the code for the same). But when we consider creating an android application, it should behave the same in all phones with different launchers. We can create a launcher for this purpose, but its not pratical to give our launcher along with our application, because the user might be used with using some other launchers.

So as a workaround, we can make use of the activity-alias in the Android Manifest.

1. As your first step, you need to create app icons with different badges. Say for example, in your application, if you need to show the unread count of messages, you can create app icons with : no-count, count as 1 to 10, count as 10+ (Planning to show the icon with no count, count from 1 to 10 and if more, show it as 10+)

2. Then in manifest for your launcher activity, create activity-aliases which corresponds to the app icons created. In the below example, the launcher activity is MainActivity and I’ve created activity-aliases for the same activity for each app icon naming from a1 to a10 and a10p

<application
    android:allowBackup="true"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.study.MainActivity"
        android:enabled="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity-alias
        android:name=".a1"
        android:enabled="false"
        android:icon="@drawable/icon_1"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a2"
        android:enabled="false"
        android:icon="@drawable/icon_2"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a3"
        android:enabled="false"
        android:icon="@drawable/icon_3"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a4"
        android:enabled="false"
        android:icon="@drawable/icon_4"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a5"
        android:enabled="false"
        android:icon="@drawable/icon_5"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a6"
        android:enabled="false"
        android:icon="@drawable/icon_6"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a7"
        android:enabled="false"
        android:icon="@drawable/icon_7"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a8"
        android:enabled="false"
        android:icon="@drawable/icon_8"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a9"
        android:enabled="false"
        android:icon="@drawable/icon_9"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a10"
        android:enabled="false"
        android:icon="@drawable/icon_10"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a10p"
        android:enabled="false"
        android:icon="@drawable/icon_10p"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
</application> 

3. After creating the activity aliases, to show the appropriate count for the application icon, you need to use the functionality of Enabling and Disabling Manifest Components.

For Example, if your current app icon is showing no count and you need to show the count as 5, then you need to disable the Manifest component “com.example.study.MainActivity” and enable the component “com.example.study.MainActivity.a5”

Code :

Random r = new Random();
        int value = r.nextInt(15); //Your value to show as badge.
        Log.i("DEMO", "Changing : " + value);

        PackageManager pm = getApplicationContext().getPackageManager();

        String lastEnabled = getLastEnabled(); //Getting last enabled from shared preference

        if (TextUtils.isEmpty(lastEnabled)) {
            lastEnabled = "com.example.study.MainActivity";
        }

        ComponentName componentName = new ComponentName(
                "com.example.study", lastEnabled);
        pm.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

        Log.i("DEMO", "Removing : " + lastEnabled);

        if (value <= 0) {
            lastEnabled = "com.example.study.MainActivity";
        } else if (value <= 10) {
            lastEnabled = "com.example.study.a" + value;
        } else {
            lastEnabled = "com.example.study.a10p";
        }

        componentName = new ComponentName("com.example.study",
                lastEnabled);
        pm.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
        Log.i("DEMO", "Adding : " + lastEnabled);
        setLastEnabled(lastEnabled); //Saving last enabled to shared pref

Method to save to preference :

private void setLastEnabled(String value) {
    SharedPreferences pref = PreferenceManager
            .getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = pref.edit();
    editor.putString("LastEnabled", value);
    editor.commit();
}

Method to fetch from Shared preference :

private String getLastEnabled() {
    SharedPreferences pref = PreferenceManager
            .getDefaultSharedPreferences(getApplicationContext());
    return pref.getString("LastEnabled", "");
}

Please keep in mind that even if we enable and disable the component, it will take some time to reflect in the UI, say 15 seconds. Because, the home activity refreshes based on following broadcasts : package_changed, package_added and package_removed , which all are protected broadcasts which can be initiated by system only.

 

Sample project : (In which the app icon changes in every 15 seconds.)

https://github.com/eldhosembabu/mathokkil

Advertisements

5 thoughts on “Showing Badge or Count in Android App Icon

  1. This solution doesnt work on my Note2.
    This only changes the app icon in the applications but not on the desktop home screen. Plus when changed it I get an error when click on the icon on the home screen. It says that the package name is changed so it cant find the app…

    • Thanks for trying my workaround. As I already mentioned in the post, even if we change the activity-alias, it will take some time to reflect the change because of the fact that we cannot trigger the refresh. So if you click your application in between (after the activity alias is changed and not yet refreshed) you will get the error. Need to find a way to trigger refresh…. 😦

      • hey eldhosembabu, your code works half way, i.e. i can set a badge count, but ‘am unable to revert back to the default state.
        please if you could post your whole project or make your working project downloadable then it would be really great. I’m stuck with this in a vital state, so sooner the better. thanks in advance . . . 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s