Cyanogen Mod 7 – Android 2.3.3 Gingerbread

It has been a long time since the announcement of Gingerbread, last year in December, and still no official update for our phones here in Europe. I definitely want to test the NativeActivity I’ve spoken before, and I would like to get root access on my phone to go further in my testing (and update relative posts on this blog).

So yesterday evening I made the big jump to bring to my Nexus One the power of the recently released Cyanogen Mod 7. I just followed the provided wiki tutorial to update the Nexus One, but here is my experience about it.

CyanogenMod Logo

So I started by backuping my data: SMS with SMS Backup & Restore, log calls with Call Log Backup & Restore, Dolphin Browser HD links with the Bookmarks to SD plug-in, and some savegames, that I all copied from my SD Card to my computer hard drive (given that other important data like Contacts, Email, Calendar and GTasks are already synchronized by Google). I forgot to save my pictures…

Then I unmounted and formated the SD Card, rebooted to the bootloader to wipe all data and restore factory settings.

I installed fastboot on my SDK tools directory, and unlocked my bootloader with:
fastboot oem unlock

I first wanted to flash the ClockworkMod 3.0.0.5 recovery for later use with the famous ROM Manager application, but this version failed to unpack the radio-image I had to flash before Cyanogen (for script compatibility error), so I fall back on the Amon_Ra’s Recovery manual method.
fastboot flash recovery /path/to/recovery-RA-nexus-v2.1.1-CM.img

I had no more trouble flashing the radio-image (passion.5.08.00.04.zip), and then the cyanogen-mod7-update (update-cm-7.0.0-N1-signed.zip) and the Google applications (gapps-gb-20110307-signed.zip). I had to wipe all data once more to boot into the new OS, but after I have been able to restore all my data, to re-download all my favorite applications. Now I can enjoy the new eye-candy tools and other gadgets from Cyanogen, I can play with the new Java and Native API or improvement from Gingerbread, and I can use “root enabled application” like ROM Manager or the “su” command line tool.

This morning, I add the good surprise to see that a ROM update was out, so I used successfully the ROM Manager application to make a full backup of my phone to the SD Card (need to reboot on ClockworkMod recovery to proceed, 350Mo written in a few minutes), to download and to flash the OS update. Quick and smooth.

So now on, stay tuned for more tips and tricks about Android development!

Adding a “What’s New” screen to your Android application

In some case, you want users of your application to explicitly approve a License before being able to use your software. Adding an EULA (End User License Agreement) screen (a Dialog) to pop at the first start of an Android Java Application, is really simple and well documented on the web.

If you want to enforce the EULA at each new release of your application (which could become quickly annoying, beware!), give a look at this linked blog post a “SimpleEula” sample code showing how to do that simply. Something like this is needed as well if you want to update the term of the license.

But what I want is a simple “What’s New” screen to show at each new release, but without the EULA annoyance and without”cancel button”. The kind of dialog we are seeing  more and more nowadays in application of the market. From the above linked example, I’ve made a really simple “What’s New” dialog, here is the WhatsNewScreen.java sample code:

public class WhatsNewScreen {
    private static final String LOG_TAG                 = "WhatsNewScreen";

    private static final String LAST_VERSION_CODE_KEY   = "last_version_code";

    private Activity            mActivity;

    // Constructor memorize the calling Activity ("context")
    public WhatsNewScreen(Activity context) {
        mActivity = context;
    }

    // Show the dialog only if not already shown for this version of the application
    public void show() {
        try {
            // Get the versionCode of the Package, which must be different (incremented) in each release on the market in the AndroidManifest.xml
            final PackageInfo packageInfo = mActivity.getPackageManager().getPackageInfo(mActivity.getPackageName(), PackageManager.GET_ACTIVITIES);

            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mActivity);
            final long lastVersionCode = prefs.getLong(LAST_VERSION_CODE_KEY, 0);

            if (packageInfo.versionCode != lastVersionCode) {
                Log.i(LOG_TAG, "versionCode " + packageInfo.versionCode + "is different from the last known version " + lastVersionCode);

                final String title = mActivity.getString(R.string.app_name) + " v" + packageInfo.versionName;

                final String message = mActivity.getString(R.string.whatsnew);

                // Show the News since last version
                AlertDialog.Builder builder = new AlertDialog.Builder(mActivity)
                        .setTitle(title)
                        .setMessage(message)
                        .setPositiveButton(android.R.string.ok, new Dialog.OnClickListener() {

                            public void onClick(DialogInterface dialogInterface, int i) {
                                // Mark this version as read
                                SharedPreferences.Editor editor = prefs.edit();
                                editor.putLong(LAST_VERSION_CODE_KEY, packageInfo.versionCode);
                                editor.commit();
                                dialogInterface.dismiss();
                            }
                        });
                builder.create().show();
            } else {
                Log.i(LOG_TAG, "versionCode " + packageInfo.versionCode + "is already known");
            }

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

}

You have to call it on the onCreate of the first activity of your application:

    /** Called when the activity is first created. */
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Layout of the main activity
        setContentView(R.layout.main);

        // Show the "What's New" screen once for each new release of the application
        new WhatsNewScreen(this).show();

        ...
    }

Here is an example of the XML string resource used res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    ...

    <string name="whatsnew">
        - Removed many SQLite exception stack\n
        - Improved the way the application launch on notification (no more multi-activity stacking)\n
        - Added this What\'s new screen\n
    </string>

    ...
</resources>

Enjoy!