How to Support Your App on Older Android Devices

652

As with any API that is under active development, sometimes as an Android developer you’ll come across a really neat feature which, it turns out, doesn’t exist in earlier versions of the API and isn’t backwards-compatible. There are a couple of ways to deal with this. One is simply to insist that users must have a given version, and to limit your app to that version. However, that can also limit the reach of your app – there are still plenty of people out there using older versions of Android. Another option, for certain features, is to make use of the Android Support Library.

Android versions use statisticsThe Android Support Library provides support in earlier API levels for a certain set of features introduced in later API levels. So even if ShinyFeature is only available for API 11, if it’s part of the Support Library, you may be able to use it and still have your app run on older devices. (What exactly will happen on the older devices will vary depending on how the feature is supported; it’s important to test it before release on as many devices and API levels as you can.) The Support Library doesn’t cover all newer features; some 3.x features just can’t be run on 2.x devices at all. But for those that it works for, it’s a neat way of extending the reach of your app without giving up on awesome newer features.

In general, it acts as a gateway: when you import and use one of the android.support.* packages, the interpreter will look at the actual API of the device it’s running on. It will then use native built-in code if possible (if the API of your device is high enough that the feature exists in core code), or the Support Library if necessary. (There are a couple of exceptions to this; for example, the AsyncTaskLoader support class. If it matters to you, check the support class docs, and, again, test thoroughly.)

Android versions pie chart

Of course, there is a cost to this. Because the library isn’t part of core code, you have to bundle it with your app; automatically increasing the size of your app by a couple of megabytes. Clearly, if every app does this, users, especially on older devices, will run low on space. So do make sure that your app will otherwise work well on older devices, and that you wouldn’t be better off writing a different version specifically targeting earlier levels of the API.

There are two levels of the Support Library: v4 and v13. v4 provides support for features introduced after API v4 (Android 1.6), and v13 provides support for features introduced after API level 13 (Android 3.2). Unsurprisingly, v4 is at present much more extensive than v13.

Using the Support Library in a project

First, you’ll need to download the Support Library via the SDK Manager (accessed either via Eclipse or via the command line). Now open your Android project and create a libsdirectory at the top level of the project directory. Find your SDK directory, and locate the JAR file for the support library you want, e.g.

[sdk-dir]/extras/android/support/v4/android-support-v4.jar

Copy this into the libs directory of your project. Finally, edit your project’s AndroidManifest.xml to set the minimum and maximum SDK versions correctly:

<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17" />

The target should be the latest release (currently 17, at time of writing), and the minimum should be 4; or if you’re using other features that don’t exist in the Support Library or in API level 4, set the minimum to whatever is appropriate for your project.

When actually using the code, you must make certain that you’re implementing the correct class; the one from the support library, not the one from the main API. Check your import statements carefully and make sure that you don’t accidentally double up when you don’t want to:

import android.support.v4.app.SearchViewCompat; // use this line... 
import android.widget.SearchView;  // not this line!

Here’s an example using the code from the last tutorial, replacing GestureDetector with GestureDetectorCompat:

import android.view.GestureDetector; 
    // still need this for MyExampleGestureListener 
import android.support.v4.view.GestureDetectorCompat;
public class GestureExampleView extends SurfaceView  
                                implements SurfaceHolder.Callback {
	
  // private class variables
  private GestureDetectorCompat detector;
  public GestureExampleView(Context context) {
    // see previous tutorial for rest of method
    detector = new GestureDetectorCompat(context, new MyExampleGestureListener());
  }
  // rest of methods as before
  
  class MyExampleGestureListener 
      extends GestureDetector.SimpleOnGestureListener {
    // This is as before; still using GestureDetector.SimpleOnGestureListener
  }
}

Compile and run and it should work smoothly just as before; but now if you find an older device it should work on that too!

Notable classes in the Support Library

Currently, one of the most popular uses of the Support Library is to use Fragments with older versions of Android. Fragments allow you to create UI component modules which manage their own layout and lifecycle, which you can then swap in and out of your app, allowing you to create a multi-pane, dynamic UI. Fragments also make it easy to reuse components and to set them up differently in different contexts (eg phone handset vs tablet).

SearchViewCompat is also handy, allowing you to use the very useful SearchView introduced in API level 11.

ActionBar is not supported by the Support Library, but using MenuCompat allows you to specify items to be used in the ActionBar when it is available.

Watch this space for later tutorials on Fragments and the ActionBar.