Friday, November 15, 2013

Android: Get iOS Style Badge App Icon


Android is not iOS and one should not try to make it so.
Android have its one way of showing notifications.
Still in Android, we have two options to do it:
1.    Use widget.  
2.    Change application / Launcher icon dynamically.

First approach:

App Widgets
App Widgets are miniature application views that can be embedded in other applications (such as the Home screen) and receive periodic updates. These views are referred to as Widgets in the user interface, and you can publish one with an App Widget provider. An application component that is able to hold other App Widgets is called an App Widget host.

The Basics
To create an App Widget, you need the following:
AppWidgetProviderInfo object
Describes the metadata for an App Widget, such as the App Widget's layout, update frequency, and the AppWidgetProvider class. This should be defined in XML.
AppWidgetProvider class implementation
Defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, enabled, disabled and deleted.
View layout

Defines the initial layout for the App Widget, defined in XML.

Widget:
1.    Create a appwidget-provider xml name it as widget_badge_icon.xml and add it in xml folder
2.    Create a widget_badge_layout .xml as per need.
3.    Create a receiver in manifest file.
4.    Create BadgeNotificationWidget Class:

public class BadgeNotificationWidgetActivity extends AppWidgetProvider {
}

5.    Create BadgeService Service Class:

add the code snippet in our onHandleIntent method:

/**
 * Update ChangeAppIcon widget.
 */
RemoteViews remoteView = new RemoteViews(
                   getApplicationContext().getPackageName(),
                   R.layout.widget_badge_layout);

ComponentName componentName = new ComponentName(
                   getApplicationContext(),
                   BadgeNotificationWidgetActivity.class);

AppWidgetManager appWidgetManager = AppWidgetManager
                   .getInstance(getApplicationContext());

Log.d("BadgeNotificationWidgetActivity",
                   "BadgeService randomNo" + randomNo);
if (randomNo == 0) {
          remoteView.setViewVisibility(R.id.badgeNum, View.GONE);
} else {
          remoteView.setViewVisibility(R.id.badgeNum, View.VISIBLE);
}

remoteView.setTextViewText(R.id.badgeNum,
                   String.valueOf(randomNo));
// apply changes to widget
appWidgetManager.updateAppWidget(componentName, remoteView);

Output:



Second approach:
Even though it is not good approach to do but our goal is to get the badge on the app icon.
Android does not allow us to change the icons. The icons are fixed on an apk compilation as a part but still we can do if the pre-defined icons are in our drawable folders.
Aliases for an activity, named by the targetActivity attribute. The target must be in the same application as the alias and it must be declared before the alias in the manifest.

Programmatically we can enable or disable the activity-alias component by setComponentEnabledSetting method of PackageManger.

Set the enabled setting for a package component (activity, receiver, service, provider). This setting will override any enabled state which may have been set by the component in its manifest.
Parameters
componentName
The component to enable
newState
The new enabled state for the component. The legal values for this state are: COMPONENT_ENABLED_STATE_ENABLED, COMPONENT_ENABLED_STATE_DISABLED and COMPONENT_ENABLED_STATE_DEFAULT The last one removes the setting, thereby restoring the component's state to whatever was set in it's manifest (or enabled, by default).
flags
Optional behavior flags: DONT_KILL_APP or 0.


getPackageManager().setComponentEnabledSetting(
new ComponentName(this,
"com.vardhan.changeappicon.ChangeAppIconActivity-" + iconPosition),
          isIconEnable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                             : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
          PackageManager.DONT_KILL_APP);


Source Code: Here
Output:




sample source code for first approach : Badge Icon Using Widget


Improvements
If you want to see an example without changing the app icon and widget then, have a look @ Android ios Style Badge App Icon like facebook, whatsapp..... This example shows badge on app icon with small changes in the application. This example code supports from API level 9

Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments. feedback are welcome.

19 comments :

  1. can i have the code for approach 1 please? I am unable to understand it. Thanks

    ReplyDelete
    Replies
    1. please find the source code for the first approach in the post

      Delete
  2. First approach is not working.. will you please when we call the UpdateBadgeService class then which EXTRA_APPWIDGET_IDS as a intent we have to passed ???

    ReplyDelete
    Replies
    1. EXTRA_APPWIDGET_IDS belongs to AppWidgetManager.

      You can get all the widget ID's:
      intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

      Update widget using appWidgetManager.updateAppWidget.

      Check the source code attached in the post.

      Delete
    2. Thanks for replying...
      But, I had already downloaded the attached source code, but in that project there is no Launcher Activity...
      so there is no icon of this sample project...
      And, this method "appWidgetManager.updateAppWidget" is called in the UpdateBadgeService.java class...
      So, My questions is now I have to called UpdateBadgeService from the activity or not ???
      If not then what I will do so that Count of notification will be shown on the App Icon ??

      Delete
    3. On request of the source code for first approach, I have been coded again. So, you can't find the same icon when you install the application and Its sample application for widget. So, you don't have any launcher.

      Check in the widget tab with SJ icon and drag and drop the widget to home screen, on tap of the icon, you can see the count on the app icon.

      Delete
    4. Yeah.. I find that thanks...
      But my problem is that i want the notification count on the App Icon.... not on the Home Screen...
      So, is there any way to do that ???

      Delete
    5. If you want to do on the app icon, then u should be able to play with "getPackageManager().setComponentEnabledSetting" method.

      Delete
    6. But "getPackageManager().setComponentEnabledSetting" which is the 2nd approach takes 15-20 seconds to refresh... which is not desirable. ..So, how the Facebook nd WhatsApp are doing it immediately the notification count on the App icon ???

      Delete
    7. facebook does the same way but I haven't checked for whatsapp.
      In android, we don't have badge style approach as iOS, the only way is to use setComponentEnabledSetting or widget.

      Delete
    8. But Facebook doesn't take 15-20 seconds to refresh... notification count will reflect immediately in it... and you can also open app at same time...
      But in our case if you will tap on app icon immediately then it will say application not installed as a Toast message...

      Delete
    9. Samsung , sony and HTC supports adding badge to the app icon.
      -----------------------------
      Samsung:

      ContentResolver localContentResolver = this.a.getContentResolver();
      Uri localUri = Uri.parse("content://com.sec.badge/apps");

      ContentValues localContentValues = new ContentValues();
      localContentValues.put("package", PACKAGE NAME);
      localContentValues.put("class", CLASS NAME);
      localContentValues.put("badgecount", number);

      update localContentResolver, if update fails then localContentResolver.insert(localUri, localContentValues);

      ----------------------
      For Sony

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

      ------------------------
      for HTC:

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

      Delete
    10. Thanks alot...
      Now i am able to insert the badge successfully.. but still the badge count is not displaying on the App icon ???
      will you please help me in displaying that badge count on the icon ??

      Delete
    11. Sure Prince Arora...
      How may I help u?

      Delete
  3. I want to display the Total badge count on the Application icon....
    And From this code :
    Samsung:

    ContentResolver localContentResolver = this.a.getContentResolver();
    Uri localUri = Uri.parse("content://com.sec.badge/apps");

    ContentValues localContentValues = new ContentValues();
    localContentValues.put("package", PACKAGE NAME);
    localContentValues.put("class", CLASS NAME);
    localContentValues.put("badgecount", number);

    Your Badge count will store in the database.. but not display that count on the App icon..

    So How we can achieve that thing (to display badhe count on the top of Application icon)???

    ReplyDelete
  4. Hi,
    I am successfully able to create and display badge and their count now....

    Thanks for your support also...

    ReplyDelete
  5. Hey,

    I had test the 2nd Approch in My Micromax A310 device and it's displaying the badge.

    But when i create application's shortcut and opening app then it's displaying App Not Not Installed and the shortcut just get invisible,

    How can I solve this?

    ReplyDelete