As Android continues to grow in leaps and bounds, sooner or later developers must draw a line in the sand. Just as you would no longer expect to find PC software written for Microsoft Windows 95, so too it is becoming increasingly difficult to purchase applications that run on Android 1.6. At the same time, developers who really understand Android’s various SDK levels and the minimum feature set associated with each can often continue to support older devices with no or very little extra work.
I know a number of my fellow engineers will disagree with me here, arguing it’s foolish to add even an extra five lines of legacy code to a brand new application if you are only going to broaden your target audience by a handful of customers — customers who haven’t bothered to upgrade their devices for the last 24 months. Maybe one day when I have millions of customers yammering for my next app I will feel that way too. For now, if I can keep or gain a handful of customers without impacting or limiting my application base as a whole I tend to make the extra effort.
A good example of keeping your target base as broad as possible can be seen when handling the back key. If you are familiar with the Android UI paradigm, you know that in the beginning all Android devices had a “hard” back key. Pressing this key navigated back through the activity stack and potentially exited your application. A common step when writing an Android application is to override this key and perform some other action, often just confirming that yes the user really intended to exit.
This override used to be done exclusively by overriding the onKeyDown() function of an activity. Later, as Android matured introducing soft and virtual keys, a specific onBackPressed() function was created as part of the API. So to support handling the back key on versions of Android prior to 2.0, the old method is used, and anything later than 2.0 requires the new API. However, many developers are not aware that by simply suppressing the lint warning, it’s quite easy to continue to support both mechanisms.
The demo code below just does that. Feel free to follow along, or download and import the entire project directly into Eclipse.
1. Create a new Android project in Eclipse. Set the minimum SDK to 1.6 and the Build SDK to 4.1. (This gives us the broadest possible range of devices.) Rename the startup activity to Main.java and the corresponding layout to main.xml.
2. In the /res/layout folder modify main.xml. For this example we need nothing more than a linear layout and a simple text field.
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#000000"
android:gravity="center">
<TextViewandroid:textColor="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Press the back key." />
</LinearLayout>
3. Now we will move on to our /src folder and the Main.java class. The onCreate() function associates our layout. The onKeyDown() method takes care of forwarding the back key press for older versions of Android. Finally the onBackPressed() function performs our customer action.
Main.java
package com.authorwjf.backkeyexample;
import android.os.Bundle; import android.view.Gravity; import android.view.KeyEvent; import android.widget.Toast; import android.annotation.SuppressLint; import android.app.Activity;
public class Main extends Activity {
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.main);
}
@SuppressLint("NewApi")@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
Toast t = Toast.makeText(this, "Android version < 2.0", Toast.LENGTH_SHORT);t.setGravity(Gravity.TOP, 0, 100);
t.show();
onBackPressed();
return true;}
return super.onKeyDown(keyCode, event); }
@Override public void onBackPressed() { Toast.makeText(this, "Back Key Captured.", Toast.LENGTH_SHORT).show(); return;}
}
At this point we are ready to test the application. Go ahead and launch two Android emulators, one running Cupcake (Figure A) and one running Jelly Bean (Figure B). Load the application to both and mash the back key a few times. Notice the difference? Except for the toast messages, the answer is no. The code behaves the same on all versions of the operating system.
Figure A
Demo running on Cupcake
Figure B
Demo running on Jelly Bean
Keep in mind I’m not advocating you “dumb” your application down to the lowest common denominator. If there is a feature your app needs, and it is only available after certain versions of Android, then break ties with previous releases. At the same time, I suggest that like in this example there will be a number of times where it can and does make sense to look for a broader solution.