Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to support multiple android version in your code?

Tags:

Take accessing contacts in android android.jar for versions 1.6 has People.CONTENT_URI for invoking contacts related info whereas in later versions we need to have api support for RawContacts.CONTENT_URI.

Same thing is true for accessing calendar for instance as its URI is changed in android 2.2.

Is there a best practice to manage all different changes without adding additional application or build separately for each version of changes?

like image 888
dhaval Avatar asked Dec 29 '10 07:12

dhaval


Video Answer


1 Answers

For my money, a very good answer is at http://android-developers.blogspot.co.uk/2010/07/how-to-have-your-cupcake-and-eat-it-too.html. However, the example there is a little more complicated than need be, so based on that, here is an example of how to cope with it when building notifications. The underlying reason this works is a consequence of how java engines interpret classes: it only looks at them when needed, so if you wrap version specific code up in a class and only create it when you know you are using that version, it all works ...

There are, as far as I can tell, two generations of approaches to creating notification, and a naming change along the way in the second. So that gives three ways to do it. For each way, create a class with the notification generation in it:

The first approach (used through to Gingerbread):

public class MyNotificationBuilderToGingerBread {
Notification notification = null;

MyNotificationBuilderToGingerBread(Context myContext, int icon, String ticker, String title, String info, Long timeStamp, PendingIntent pendingIntent, int flags) {
    notification = new Notification(R.drawable.ic_sb, ticker, timeStamp);
    notification.setLatestEventInfo(myContext, title, info, pendingIntent);
    notification.flags |= flags;        
}

Notification get() {
    return notification;
}
}

The second approach, Honeycomb to IceCreamSandwich:

public class MyNotificationBuilderHoneyCombToIceCreamSandwich {
Notification.Builder mb = null;

MyNotificationBuilderHoneyCombToIceCreamSandwich(Context myContext, int icon, String ticker, String title, String info, Long timeStamp, PendingIntent pendingIntent, boolean onGoing) {
    mb = new Notification.Builder(myContext);
    mb.setSmallIcon(icon);
    mb.setContentIntent(pendingIntent);
    mb.setContentTitle(title);
    mb.setContentText(info);
    mb.setWhen(timeStamp);
    if (ticker != null) mb.setTicker(ticker);       
    mb.setOngoing(onGoing);
}

Notification get() {
    return mb.getNotification();
}   
}

The second generation, with the name change, Jellybean (onwards, so far ...):

public class MyNotificationBuilderJellyBean {

Notification.Builder mb = null;

MyNotificationBuilderJellyBean(Context myContext, int icon, String ticker, String title, String info, Long timeStamp, PendingIntent pendingIntent, boolean onGoing) {
    mb = new Notification.Builder(myContext);
    mb.setSmallIcon(icon);
    mb.setContentIntent(pendingIntent);
    mb.setContentTitle(title);
    mb.setContentText(info);
    mb.setWhen(timeStamp);
    if (ticker != null) mb.setTicker(ticker);       
    mb.setOngoing(onGoing);
}

Notification get() {
    return mb.build();
}   
}

Then, you just need to pick which class to instantiate on the fly:

// System information
private final int sdkVersion = Build.VERSION.SDK_INT;
// If you want to go really old:
    // (actually, there is a question about how this issue should be handled
    // systematically. Suggestions welcome.)
// final int sdkVersion = Integer.parseInt(Build.VERSION.SDK);

    // This is for a permanent notification. Change the final argument (flags or boolean) if it isn't meant ot be
    // For meaning of other variable, see notification documentation on the android website.
    if (sdkVersion < Build.VERSION_CODES.HONEYCOMB) {
        MyNotificationBuilderToGingerBread mnb = new MyNotificationBuilderToGingerBread(myContext, R.drawable.notification_icon, ticketText, title, infoText, timeStampMillis, pendingIntentForTapOnFullNotitifcation, Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR);
        notification = mnb.get();
    }
    else if (sdkVersion < Build.VERSION_CODES.JELLY_BEAN) {
        MyNotificationBuilderHoneyCombToIceCreamSandwich mnb = new MyNotificationBuilderHoneyCombToIceCreamSandwich(myContext, R.drawable.notification_icon, ticketText, title, infoText, timeStampMillis, pendingIntentForTapOnFullNotitifcation, true);
        notification = mnb.get();
    }
    else {
        MyNotificationBuilderJellyBean mnb = new MyNotificationBuilderJellyBean(myContext, R.drawable.notification_icon, ticketText, title, infoText, timeStampMillis, pendingIntentForTapOnFullNotitifcation, true);
        notification = mnb.get();
    }

    // Send the notification.
    notificationManager.notify(idForNotificationManager, notification);

Hope this helps!

like image 181
Neil Townsend Avatar answered Oct 04 '22 21:10

Neil Townsend