The integration of gestures into your android app adds some nice functionality and is made very easy using Google’s GestureBuilder application and the integrated GestureLibrary and Gesture Overlay API – so let’s build a sample app.

If you need some basic information regarding gestures on android first – take a look at this article.

Creating a gesture library

First you need to define the gestures that should be captured in the application later. For this reason there’s the GestureBuilder delivered with the Android SDK. You can find the app in the samples directory of your android sdk – e.g. <installation-directory>/android-sdk-linux_86/platforms/android-2.1/samples/GestureBuilder.

Run the gesture builder app on the android emulator. It is important to run the app with a SD card connected – if you need more information on creating virtual SD cards – take a look at this article. The important thing is to start the emulator with -sdcard <path-to-virtual-sdcard>/<sdcard-image>. The app needs the sdcard to store the captured gestures on it.

Running the GestureBuilder you need to add a new gesture – for this tutorial I’m capturing one gesture by drawing a spiral and naming it to “test”.

Example 1. Handling Gestures

gesture builder start 203x300 gesture builder capturing 202x300 gesture builder overview 200x300

Copy the gesture library from the SD card – e.g. by opening the view Android File Explorer in Eclipse and save it somewhere for now.

file explorer
Figure 1. Eclipse IDE - Android File Explorer

Capturing Gestures

First create a new android application using the android sdk – my AndroidManifest.xml looks like this

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.hascode.android.tutorial"
     android:versionCode="1"
     android:versionName="1.0">
         <application android:icon="@drawable/icon" android:label="@string/app_name">
             <activity android:name=".GestureActivity"
             android:label="@string/app_name">
                 <intent-filter>
                     <action android:name="android.intent.action.MAIN" />
                     <category android:name="android.intent.category.LAUNCHER" />
                 </intent-filter>
             </activity>
         </application>
</manifest>

My strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">hasCode.com - Gesture Tutorial</string>
</resources>

Create directory res/raw if it doesn’t exist yet and put the downloaded gesture library “gesture” in there

Now create an activity called GestureActivity and reference the gesture library – my class looks like this

package com.hascode.android.tutorial;

import java.util.ArrayList;

import android.app.Activity;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.os.Bundle;
import android.util.Log;

/**
 * A simple Activity listening for Gestures
 *
 * visit https://www.hascode.com
 */
public class GestureActivity extends Activity {
	private GestureLibrary gLib;
	private static final String TAG = "com.hascode.android.gesture";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		gLib = GestureLibraries.fromRawResource(this, R.raw.gesture);
		if (!gLib.load()) {
			Log.w(TAG, "could not load gesture library");
			finish();
		}
	}
}

Now we need a gesture overlay – we’re adding it to the main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Try to draw the gesture"
    />
<android.gesture.GestureOverlayView
    android:id="@+id/gestures"
    android:layout_width="fill_parent"
    android:layout_height="0dip"
    android:layout_weight="1.0" />
</LinearLayout>

Add an event listener to the activity and reference the gesture overlay in the GestureActivity – at last my class looks like this:

package com.hascode.android.tutorial;

import java.util.ArrayList;

import android.app.Activity;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.Prediction;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

/**
 * A simple Activity listening for Gestures
 *
 * visit https://www.hascode.com
 */
public class GestureActivity extends Activity {
	private GestureLibrary gLib;
	private static final String TAG = "com.hascode.android.gesture";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		gLib = GestureLibraries.fromRawResource(this, R.raw.gesture);
		if (!gLib.load()) {
			Log.w(TAG, "could not load gesture library");
			finish();
		}

		GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
		gestures.addOnGesturePerformedListener(handleGestureListener);
	}

	/**
	 * our gesture listener
	 */
	private OnGesturePerformedListener handleGestureListener = new OnGesturePerformedListener() {
		@Override
		public void onGesturePerformed(GestureOverlayView gestureView,
				Gesture gesture) {

			ArrayList<Prediction> predictions = gLib.recognize(gesture);

			// one prediction needed
			if (predictions.size() > 0) {
				Prediction prediction = predictions.get(0);
				// checking prediction
				if (prediction.score > 1.0) {
					// and action
					Toast.makeText(GestureActivity.this, prediction.name,
							Toast.LENGTH_SHORT).show();
				}
			}

		}
	};
}

Testing the Gesture

Now run the application and draw the spiral and a toast showing the gesture’s name (I named it “test”) pops up:

gesture app drawing 300x202

gesture app result 213x300

Article Updates

  • 2015-03-03: Table of contents added.