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!

CMake for Android

Last time, we’ve seen how to install and test the standalone toolchain of the NDK to build a native shared library with a standard Makefile & make command under Linux.

CMake LogoBut nowadays, many open source libraries and projects does not directly come with a Makefile, instead using a build system to automate its generation. CMake is becoming more and more used for those kind of jobs, so being able to use it for Android is really interesting. And easy!

A CMake configuration file for Android (android.toolchain.cmake) is provided by the android-cmake Google project hosted on Mercurial (see my previous post on Mercurial). Let’s clone its repository in the home directory with the following commands:
hg clone https://android-cmake.googlecode.com/hg/ android-cmake
Then, add to your .bashrc the ANDROID_NDK_TOOLCHAIN_ROOT and ANDTOOLCHAIN environment variables pointing to NDK and to the cmake config file. I also added a simple alias for later use:

PATH=$PATH:$HOME/android-sdk-linux_x86/tools
PATH=$PATH:$HOME/android-sdk-linux_x86/platform-tools
PATH=$PATH:$HOME/android-ndk-r5b/standalone-toolchain-api5/bin/

ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-ndk-r5b/standalone-toolchain-api5
ANDTOOLCHAIN=$HOME/android-cmake/toolchain/android.toolchain.cmake

alias cmake-android='cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN'

Ok, let’s try to compile the “hello-cmake” sample provided by the Google project (see hello-cmake documentation):

cd ~/android-cmake/samples/hello-cmake/
mkdir build
cd build
export ANDROID_NDK_TOOLCHAIN_ROOT
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN ..

We can simplify the last command by using our alias, so next type we will use “cmake-android ..” instead.
At this stage, CMake has generated the Makefile for you. Use it to build the sample :
make
Here you are, the shared library has been build and is ready for integration in an Application. You can find it here:
~/android-cmake/samples/hello-cmake/libs/armeabi-v7a/libhello-cmake.so
Now we want to invoke this native library from a Java Application, using JNI. This is documented in the next provided sample, “hello-android-cmake“, which is the Java counterpart of the C application we’ve build.

Copy the above “libs” directory to ~/android-cmake/samples/hello-android-cmake. Then open Eclipse and start a “File->New…->Project…->Android Project”. Select “create project from existing source” and give it the ~/android-cmake/samples/hello-android-cmake path.

Build the application, and launch it on an emulator or an actual device. You should see an activity showing the multi-line text starting by “JNI — pi = 3.14159…” coming from our shared library !

Hello Android CMake

Here you are!