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.

Thursday, November 7, 2013

Google Maps Android API v2 : mapFragment.getMap() returns null


If mapFragment.getMap() returns null then map is not verified from the GooglePlayServices.

Google Play Services
Give apps more features to attract users on a wider range of devices. With Google Play services, our app can take advantage of the latest, Google-powered features such as Maps, Google+, and more, with automatic platform updates distributed as an APK through the Google Play store.

This type of exception occurs when there are no proper GooglePlayServices updates.
We can check using GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) method, Which returns status code indicating whether there was an error or not.

public static int isGooglePlayServicesAvailable (Context context)
Verifies that Google Play services is installed and enabled on this device, and that the version installed on this device is no older than the one required by this client.
Returns
status code indicating whether there was an error. Can be one of following in ConnectionResult: SUCCESS, SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, SERVICE_DISABLED, SERVICE_INVALID, DATE_INVALID.

Map the output of GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) return value with ConnectionResult class Constants. We can find the response of GooglePlayServices.

Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment = (SupportMapFragment) fragment;
map = mapFragment.getMap();

if (map != null) {
// The Map is verified. It is now safe to manipulate the map.
}else {
int checkGooglePlayServices = GooglePlayServicesUtil
              .isGooglePlayServicesAvailable(this);
       if (checkGooglePlayServices != ConnectionResult.SUCCESS) {
              // google play services is missing!!!!
              /*
               * Returns status code indicating whether there was an error.
               * Can be one of following in ConnectionResult: SUCCESS,
               * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED,
               * SERVICE_DISABLED, SERVICE_INVALID.
               */
              GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices,
                     this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
       }
}

Below are the error codes used by GooglePlayServicesClient.OnConnectionFailedListener

Constants
int
The device date is likely set incorrectly.
int
The application is misconfigured.
int
The Drive API requires external storage (such as an SD card), but no external storage is mounted.
int
An internal error occurred.
int
The client attempted to connect to the service with an invalid account name specified.
int
The application is not licensed to the user.
int
A network error occurred.
int
Completing the connection requires some form of resolution.
int
The installed version of Google Play services has been disabled on this device.
int
The version of the Google Play services installed on this device is not authentic.
int
Google Play services is missing on this device.
int
The installed version of Google Play services is out of date.
int
The client attempted to connect to the service but the user is not signed in.
int
The connection was successful.


Note: Do Google Play Services Verification when we are using services of Google.

Origin References: