Android Tutorial - User Event : GestureStore

 Set Orientation Style: GestureStore.ORIENTATION_INVARIANT

  

        
package app.test;

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.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.GestureStore;
import android.gesture.Prediction;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class Test extends Activity implements OnGesturePerformedListener {
    private static final String TAG = "Gesture Revealer";
  GestureLibrary gestureLib = null;

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

//        gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures_letters);
        gestureLib = GestureLibraries.fromFile("/sdcard/gestures");
        gestureLib.setOrientationStyle(GestureStore.ORIENTATION_INVARIANT);
        gestureLib.setSequenceType(GestureStore.SEQUENCE_INVARIANT);

        if (!gestureLib.load()) {
            Toast.makeText(this, "Could not load /sdcard/gestures", Toast.LENGTH_SHORT).show();
            finish();
        }
        Log.v(TAG, "  Orientation style: " + gestureLib.getOrientationStyle());
        Log.v(TAG, "  Sequence type: " + gestureLib.getSequenceType());
        for( String gestureName : gestureLib.getGestureEntries() ) {
          Log.v(TAG, "For gesture " + gestureName);
          int i = 1;
            for( Gesture gesture : gestureLib.getGestures(gestureName) ) {
              Log.v(TAG, "    " + i + ": ID: " + gesture.getID());
              Log.v(TAG, "    " + i + ": Strokes count: " + gesture.getStrokesCount());
              Log.v(TAG, "    " + i + ": Stroke length: " + gesture.getLength());
              i++;
            }
        }

        GestureOverlayView gestureView = (GestureOverlayView) findViewById(R.id.gestureOverlay);
        gestureView.addOnGesturePerformedListener(this);
        gestureView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
    }

  public void onGesturePerformed(GestureOverlayView view, Gesture gesture) {
      ArrayList<Prediction> predictions = gestureLib.recognize(gesture);
      if (predictions.size() > 0) {
          Prediction prediction = (Prediction) predictions.get(0);
          if (prediction.score > 1.0) {
              Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
              for(int i=0;i<predictions.size();i++)
                Log.v(TAG, "prediction " + predictions.get(i).name +
                    " - score = " + predictions.get(i).score);
          }
      }
  }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/main.xml -->
<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="Draw gestures and I'll guess what they are"
    />
    
<android.gesture.GestureOverlayView
    android:id="@+id/gestureOverlay"
    android:layout_width="fill_parent"  android:layout_height="fill_parent"
    android:gestureStrokeType="multiple"  android:fadeOffset="1000"
    />

</LinearLayout>
Guesture Builder
package app.test;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.MotionEvent;
import android.gesture.GestureOverlayView;
import android.gesture.Gesture;
import android.gesture.GestureLibrary;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;

import android.app.Dialog;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.os.Bundle;
import android.os.AsyncTask;
import android.os.Environment;
import android.view.View;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.gesture.GestureLibrary;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.ArrayAdapter;
import android.content.DialogInterface;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.text.TextUtils;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.BitmapDrawable;

import java.util.Map;
import java.util.Collections;
import java.util.HashMap;
import java.util.Comparator;
import java.util.Set;
import java.io.File;

 class GestureBuilderActivity extends ListActivity {
    private static final int STATUS_SUCCESS = 0;
    private static final int STATUS_CANCELLED = 1;
    private static final int STATUS_NO_STORAGE = 2;
    private static final int STATUS_NOT_LOADED = 3;

    private static final int MENU_ID_RENAME = 1;
    private static final int MENU_ID_REMOVE = 2;

    private static final int DIALOG_RENAME_GESTURE = 1;

    private static final int REQUEST_NEW_GESTURE = 1;
    
    // Type: long (id)
    private static final String GESTURES_INFO_ID = "gestures.info_id";

    private final File mStoreFile = new File(Environment.getExternalStorageDirectory(), "gestures");

    private final Comparator<NamedGesture> mSorter = new Comparator<NamedGesture>() {
        public int compare(NamedGesture object1, NamedGesture object2) {
            return object1.name.compareTo(object2.name);
        }
    };

    private static GestureLibrary sStore;

    private GesturesAdapter mAdapter;
    private GesturesLoadTask mTask;
    private TextView mEmpty;

    private Dialog mRenameDialog;
    private EditText mInput;
    private NamedGesture mCurrentRenameGesture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.gestures_list);

        mAdapter = new GesturesAdapter(this);
        setListAdapter(mAdapter);

        if (sStore == null) {
            sStore = GestureLibraries.fromFile(mStoreFile);
        }
        mEmpty = (TextView) findViewById(android.R.id.empty);
        loadGestures();

        registerForContextMenu(getListView());
    }

    static GestureLibrary getStore() {
        return sStore;
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public void reloadGestures(View v) {
        loadGestures();
    }
    
    @SuppressWarnings({"UnusedDeclaration"})
    public void addGesture(View v) {
        Intent intent = new Intent(this, CreateGestureActivity.class);
        startActivityForResult(intent, REQUEST_NEW_GESTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case REQUEST_NEW_GESTURE:
                    loadGestures();
                    break;
            }
        }
    }

    private void loadGestures() {
        if (mTask != null && mTask.getStatus() != GesturesLoadTask.Status.FINISHED) {
            mTask.cancel(true);
        }        
        mTask = (GesturesLoadTask) new GesturesLoadTask().execute();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mTask != null && mTask.getStatus() != GesturesLoadTask.Status.FINISHED) {
            mTask.cancel(true);
            mTask = null;
        }

        cleanupRenameDialog();
    }

    private void checkForEmpty() {
        if (mAdapter.getCount() == 0) {
            mEmpty.setText(R.string.gestures_empty);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        if (mCurrentRenameGesture != null) {
            outState.putLong(GESTURES_INFO_ID, mCurrentRenameGesture.gesture.getID());
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle state) {
        super.onRestoreInstanceState(state);

        long id = state.getLong(GESTURES_INFO_ID, -1);
        if (id != -1) {
            final Set<String> entries = sStore.getGestureEntries();
out:        for (String name : entries) {
                for (Gesture gesture : sStore.getGestures(name)) {
                    if (gesture.getID() == id) {
                        mCurrentRenameGesture = new NamedGesture();
                        mCurrentRenameGesture.name = name;
                        mCurrentRenameGesture.gesture = gesture;
                        break out;
                    }
                }
            }
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenu.ContextMenuInfo menuInfo) {

        super.onCreateContextMenu(menu, v, menuInfo);

        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        menu.setHeaderTitle(((TextView) info.targetView).getText());

        menu.add(0, MENU_ID_RENAME, 0, R.string.gestures_rename);
        menu.add(0, MENU_ID_REMOVE, 0, R.string.gestures_delete);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo)
                item.getMenuInfo();
        final NamedGesture gesture = (NamedGesture) menuInfo.targetView.getTag();

        switch (item.getItemId()) {
            case MENU_ID_RENAME:
                renameGesture(gesture);
                return true;
            case MENU_ID_REMOVE:
                deleteGesture(gesture);
                return true;
        }

        return super.onContextItemSelected(item);
    }

    private void renameGesture(NamedGesture gesture) {
        mCurrentRenameGesture = gesture;
        showDialog(DIALOG_RENAME_GESTURE);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        if (id == DIALOG_RENAME_GESTURE) {
            return createRenameDialog();
        }
        return super.onCreateDialog(id);
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        super.onPrepareDialog(id, dialog);
        if (id == DIALOG_RENAME_GESTURE) {
            mInput.setText(mCurrentRenameGesture.name);
        }
    }

    private Dialog createRenameDialog() {
        final View layout = View.inflate(this, R.layout.dialog_rename, null);
        mInput = (EditText) layout.findViewById(R.id.name);
        ((TextView) layout.findViewById(R.id.label)).setText(R.string.gestures_rename_label);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setIcon(0);
        builder.setTitle(getString(R.string.gestures_rename_title));
        builder.setCancelable(true);
        builder.setOnCancelListener(new Dialog.OnCancelListener() {
            public void onCancel(DialogInterface dialog) {
                cleanupRenameDialog();
            }
        });
        builder.setNegativeButton(getString(R.string.cancel_action),
            new Dialog.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    cleanupRenameDialog();
                }
            }
        );
        builder.setPositiveButton(getString(R.string.rename_action),
            new Dialog.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    changeGestureName();
                }
            }
        );
        builder.setView(layout);
        return builder.create();
    }

    private void changeGestureName() {
        final String name = mInput.getText().toString();
        if (!TextUtils.isEmpty(name)) {
            final NamedGesture renameGesture = mCurrentRenameGesture;
            final GesturesAdapter adapter = mAdapter;
            final int count = adapter.getCount();

            // Simple linear search, there should not be enough items to warrant
            // a more sophisticated search
            for (int i = 0; i < count; i++) {
                final NamedGesture gesture = adapter.getItem(i);
                if (gesture.gesture.getID() == renameGesture.gesture.getID()) {
                    sStore.removeGesture(gesture.name, gesture.gesture);
                    gesture.name = mInput.getText().toString();
                    sStore.addGesture(gesture.name, gesture.gesture);
                    break;
                }
            }

            adapter.notifyDataSetChanged();
        }
        mCurrentRenameGesture = null;
    }

    private void cleanupRenameDialog() {
        if (mRenameDialog != null) {
            mRenameDialog.dismiss();
            mRenameDialog = null;
        }
        mCurrentRenameGesture = null;
    }

    private void deleteGesture(NamedGesture gesture) {
        sStore.removeGesture(gesture.name, gesture.gesture);
        sStore.save();

        final GesturesAdapter adapter = mAdapter;
        adapter.setNotifyOnChange(false);
        adapter.remove(gesture);
        adapter.sort(mSorter);
        checkForEmpty();
        adapter.notifyDataSetChanged();

        Toast.makeText(this, R.string.gestures_delete_success, Toast.LENGTH_SHORT).show();
    }

    private class GesturesLoadTask extends AsyncTask<Void, NamedGesture, Integer> {
        private int mThumbnailSize;
        private int mThumbnailInset;
        private int mPathColor;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            final Resources resources = getResources();
            mPathColor = resources.getColor(R.color.gesture_color);
            mThumbnailInset = (int) resources.getDimension(R.dimen.gesture_thumbnail_inset);
            mThumbnailSize = (int) resources.getDimension(R.dimen.gesture_thumbnail_size);

            findViewById(R.id.addButton).setEnabled(false);
            findViewById(R.id.reloadButton).setEnabled(false);
            
            mAdapter.setNotifyOnChange(false);            
            mAdapter.clear();
        }

        @Override
        protected Integer doInBackground(Void... params) {
            if (isCancelled()) return STATUS_CANCELLED;
            if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                return STATUS_NO_STORAGE;
            }

            final GestureLibrary store = sStore;

            if (store.load()) {
                for (String name : store.getGestureEntries()) {
                    if (isCancelled()) break;

                    for (Gesture gesture : store.getGestures(name)) {
                        final Bitmap bitmap = gesture.toBitmap(mThumbnailSize, mThumbnailSize,
                                mThumbnailInset, mPathColor);
                        final NamedGesture namedGesture = new NamedGesture();
                        namedGesture.gesture = gesture;
                        namedGesture.name = name;

                        mAdapter.addBitmap(namedGesture.gesture.getID(), bitmap);
                        publishProgress(namedGesture);
                    }
                }

                return STATUS_SUCCESS;
            }

            return STATUS_NOT_LOADED;
        }

        @Override
        protected void onProgressUpdate(NamedGesture... values) {
            super.onProgressUpdate(values);

            final GesturesAdapter adapter = mAdapter;
            adapter.setNotifyOnChange(false);

            for (NamedGesture gesture : values) {
                adapter.add(gesture);
            }

            adapter.sort(mSorter);
            adapter.notifyDataSetChanged();
        }

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);

            if (result == STATUS_NO_STORAGE) {
                getListView().setVisibility(View.GONE);
                mEmpty.setVisibility(View.VISIBLE);
                mEmpty.setText(getString(R.string.gestures_error_loading,
                        mStoreFile.getAbsolutePath()));
            } else {
                findViewById(R.id.addButton).setEnabled(true);
                findViewById(R.id.reloadButton).setEnabled(true);
                checkForEmpty();
            }
        }
    }

    static class NamedGesture {
        String name;
        Gesture gesture;
    }

    private class GesturesAdapter extends ArrayAdapter<NamedGesture> {
        private final LayoutInflater mInflater;
        private final Map<Long, Drawable> mThumbnails = Collections.synchronizedMap(
                new HashMap<Long, Drawable>());

        public GesturesAdapter(Context context) {
            super(context, 0);
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        void addBitmap(Long id, Bitmap bitmap) {
            mThumbnails.put(id, new BitmapDrawable(bitmap));
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.gestures_item, parent, false);
            }

            final NamedGesture gesture = getItem(position);
            final TextView label = (TextView) convertView;

            label.setTag(gesture);
            label.setText(gesture.name);
            label.setCompoundDrawablesWithIntrinsicBounds(mThumbnails.get(gesture.gesture.getID()),
                    null, null, null);

            return convertView;
        }
    }
}

public class CreateGestureActivity extends Activity {
    private static final float LENGTH_THRESHOLD = 120.0f;

    private Gesture mGesture;
    private View mDoneButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.create_gesture);

        mDoneButton = findViewById(R.id.done);

        GestureOverlayView overlay = (GestureOverlayView) findViewById(R.id.gestures_overlay);
        overlay.addOnGestureListener(new GesturesProcessor());
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        
        if (mGesture != null) {
            outState.putParcelable("gesture", mGesture);
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        
        mGesture = savedInstanceState.getParcelable("gesture");
        if (mGesture != null) {
            final GestureOverlayView overlay =
                    (GestureOverlayView) findViewById(R.id.gestures_overlay);
            overlay.post(new Runnable() {
                public void run() {
                    overlay.setGesture(mGesture);
                }
            });

            mDoneButton.setEnabled(true);
        }
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public void addGesture(View v) {
        if (mGesture != null) {
            final TextView input = (TextView) findViewById(R.id.gesture_name);
            final CharSequence name = input.getText();
            if (name.length() == 0) {
                input.setError(getString(R.string.error_missing_name));
                return;
            }

            final GestureLibrary store = GestureBuilderActivity.getStore();
            store.addGesture(name.toString(), mGesture);
            store.save();

            setResult(RESULT_OK);

            final String path = new File(Environment.getExternalStorageDirectory(),
                    "gestures").getAbsolutePath();
            Toast.makeText(this, getString(R.string.save_success, path), Toast.LENGTH_LONG).show();
        } else {
            setResult(RESULT_CANCELED);
        }

        finish();
        
    }
    
    @SuppressWarnings({"UnusedDeclaration"})
    public void cancelGesture(View v) {
        setResult(RESULT_CANCELED);
        finish();
    }
    
    private class GesturesProcessor implements GestureOverlayView.OnGestureListener {
        public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
            mDoneButton.setEnabled(false);
            mGesture = null;
        }

        public void onGesture(GestureOverlayView overlay, MotionEvent event) {
        }

        public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
            mGesture = overlay.getGesture();
            if (mGesture.getLength() < LENGTH_THRESHOLD) {
                overlay.clear(false);
            }
            mDoneButton.setEnabled(true);
        }

        public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
        }
    }
}
//res\layout\create_gesture.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        android:orientation="horizontal">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="6dip"
            
            android:text="@string/prompt_gesture_name"
            android:textAppearance="?android:attr/textAppearanceMedium" />
        
        <EditText
            android:id="@+id/gesture_name"
            android:layout_width="0dip"
            android:layout_weight="1.0"
            android:layout_height="wrap_content"

            android:maxLength="40"
            android:singleLine="true" />

    </LinearLayout>
    
    <android.gesture.GestureOverlayView
        android:id="@+id/gestures_overlay"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1.0"

        android:gestureStrokeType="multiple" />

    <LinearLayout
        style="@android:style/ButtonBar"

        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        android:orientation="horizontal">

        <Button
            android:id="@+id/done"
                
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"

            android:enabled="false"

            android:onClick="addGesture"
            android:text="@string/button_done" />
    
        <Button
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            
            android:onClick="cancelGesture"
            android:text="@string/button_discard" />
    
    </LinearLayout>
    
</LinearLayout>



//res\layout\dialog_rename.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="20dip"
    android:orientation="vertical">

    <TextView
        android:id="@+id/label"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="@string/gestures_rename_label"
        android:gravity="left"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <EditText
        android:id="@+id/name"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:scrollHorizontally="true"
        android:autoText="false"
        android:capitalize="none"
        android:gravity="fill_horizontal"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>



//res\layout\gestures_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeight"

    android:drawablePadding="12dip"
    android:paddingLeft="6dip"
    android:paddingRight="6dip"

    android:ellipsize="marquee"
    android:singleLine="true"
    android:textAppearance="?android:attr/textAppearanceLarge" />



//res\layout\gestures_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:orientation="vertical">

    <ListView
        android:id="@android:id/list"

        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1.0" />

    <TextView
        android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1.0"

        android:gravity="center"

        android:text="@string/gestures_loading"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <LinearLayout
        style="@android:style/ButtonBar"

        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        android:orientation="horizontal">

        <Button
            android:id="@+id/addButton"
            android:onClick="addGesture"

            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"

            android:enabled="false"
            android:text="@string/button_add" />

        <Button
            android:id="@+id/reloadButton"
            android:onClick="reloadGestures"

            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"

            android:enabled="false"
            android:text="@string/button_reload" />

    </LinearLayout>

</LinearLayout>




//res\values\colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="gesture_color">#FFFFFF00</color>
</resources>



//res\values\dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="gesture_thumbnail_inset">8dip</dimen>
    <dimen name="gesture_thumbnail_size">64dip</dimen>
</resources>



//res\values\strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- General -->
    <skip />
    <!-- Application name -->
    <string name="application_name">Gestures Builder</string>
    <!-- Title, name of the activity used to create a gesture -->
    <string name="label_create_gesture">Create a gesture</string>

    <!-- Buttons -->
    <skip />
    <!-- Label, button used to add a gesture -->
    <string name="button_add">Add gesture</string>
    <!-- Label, button used to reload all gestures -->
    <string name="button_reload">Reload</string>
    <!-- Label, button used to cancel the operation of adding a gesture -->
    <string name="button_discard">Discard</string>
    <!-- Label, button used to save a gesture newly created -->
    <string name="button_done">Done</string>
    
    <!-- Gestures -->
    <skip />
    <!-- Label, prompt asking the user to enter the name of the gesture -->
    <string name="prompt_gesture_name">Name</string>
    <!-- Error message, informs the user he needs to enter a name before saving a gesture -->
    <string name="error_missing_name">You must enter a name</string>
    <!-- success message, tells the user where the gesture was saved -->
    <string name="save_success">Gesture saved in %s</string>
    <!-- Buttons in Rename gesture dialog box -->
    <string name="rename_action">OK</string>
    <!-- Buttons in Rename gesture dialog box -->
    <string name="cancel_action">Cancel</string>
    <!-- Message displayed when the user opens the gestures settings screen -->
    <string name="gestures_loading">Loading gestures...</string>
    <!-- Message displayed when the user has no gestures -->
    <string name="gestures_empty">No gestures</string>
    <!-- Title of the screen used to view/manage gestures -->
    <string name="gestures_activity">Gestures</string>
    <!-- Noun, menu item used to rename a gesture -->
    <string name="gestures_rename">Rename</string>
    <!-- Noun, menu item used to remove a gesture -->
    <string name="gestures_delete">Delete</string>
    <!-- Message displayed when a gesture is successfully deleted -->
    <string name="gestures_delete_success">Gesture deleted</string>
    <!-- Title of dialog box -->
    <string name="gestures_rename_title">Rename gesture</string>
    <!-- Label of gesture name field in Rename gesture dialog box -->
    <string name="gestures_rename_label">Gesture name</string>
    <!-- Message, displayed when the sdcard cannot be found, 1st parameter is the name of the file that stores the gestures.  CHAR LIMIT=80 -->
    <string name="gestures_error_loading">Could not load %s. Make sure you have storage available.</string>
</resources>

Load Gesture Libraries

   

        
package app.test;

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.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.GestureStore;
import android.gesture.Prediction;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class Test extends Activity implements OnGesturePerformedListener {
    private static final String TAG = "Gesture Revealer";
  GestureLibrary gestureLib = null;

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

//        gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures_letters);
        gestureLib = GestureLibraries.fromFile("/sdcard/gestures");
        gestureLib.setOrientationStyle(GestureStore.ORIENTATION_INVARIANT);
        gestureLib.setSequenceType(GestureStore.SEQUENCE_INVARIANT);

        if (!gestureLib.load()) {
            Toast.makeText(this, "Could not load /sdcard/gestures", Toast.LENGTH_SHORT).show();
            finish();
        }
        Log.v(TAG, "  Orientation style: " + gestureLib.getOrientationStyle());
        Log.v(TAG, "  Sequence type: " + gestureLib.getSequenceType());
        for( String gestureName : gestureLib.getGestureEntries() ) {
          Log.v(TAG, "For gesture " + gestureName);
          int i = 1;
            for( Gesture gesture : gestureLib.getGestures(gestureName) ) {
              Log.v(TAG, "    " + i + ": ID: " + gesture.getID());
              Log.v(TAG, "    " + i + ": Strokes count: " + gesture.getStrokesCount());
              Log.v(TAG, "    " + i + ": Stroke length: " + gesture.getLength());
              i++;
            }
        }

        GestureOverlayView gestureView = (GestureOverlayView) findViewById(R.id.gestureOverlay);
        gestureView.addOnGesturePerformedListener(this);
        gestureView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
    }

  public void onGesturePerformed(GestureOverlayView view, Gesture gesture) {
      ArrayList<Prediction> predictions = gestureLib.recognize(gesture);
      if (predictions.size() > 0) {
          Prediction prediction = (Prediction) predictions.get(0);
          if (prediction.score > 1.0) {
              Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
              for(int i=0;i<predictions.size();i++)
                Log.v(TAG, "prediction " + predictions.get(i).name +
                    " - score = " + predictions.get(i).score);
          }
      }
  }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/main.xml -->
<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="Draw gestures and I'll guess what they are"
    />
    
<android.gesture.GestureOverlayView
    android:id="@+id/gestureOverlay"
    android:layout_width="fill_parent"  android:layout_height="fill_parent"
    android:gestureStrokeType="multiple"  android:fadeOffset="1000"
    />

</LinearLayout>

Set Gesture Sequence Type

   

        
package app.test;

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.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.GestureStore;
import android.gesture.Prediction;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class Test extends Activity implements OnGesturePerformedListener {
    private static final String TAG = "Gesture Revealer";
  GestureLibrary gestureLib = null;

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

//        gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures_letters);
        gestureLib = GestureLibraries.fromFile("/sdcard/gestures");
        gestureLib.setOrientationStyle(GestureStore.ORIENTATION_INVARIANT);
        gestureLib.setSequenceType(GestureStore.SEQUENCE_INVARIANT);

        if (!gestureLib.load()) {
            Toast.makeText(this, "Could not load /sdcard/gestures", Toast.LENGTH_SHORT).show();
            finish();
        }
        Log.v(TAG, "  Orientation style: " + gestureLib.getOrientationStyle());
        Log.v(TAG, "  Sequence type: " + gestureLib.getSequenceType());
        for( String gestureName : gestureLib.getGestureEntries() ) {
          Log.v(TAG, "For gesture " + gestureName);
          int i = 1;
            for( Gesture gesture : gestureLib.getGestures(gestureName) ) {
              Log.v(TAG, "    " + i + ": ID: " + gesture.getID());
              Log.v(TAG, "    " + i + ": Strokes count: " + gesture.getStrokesCount());
              Log.v(TAG, "    " + i + ": Stroke length: " + gesture.getLength());
              i++;
            }
        }

        GestureOverlayView gestureView = (GestureOverlayView) findViewById(R.id.gestureOverlay);
        gestureView.addOnGesturePerformedListener(this);
        gestureView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
    }

  public void onGesturePerformed(GestureOverlayView view, Gesture gesture) {
      ArrayList<Prediction> predictions = gestureLib.recognize(gesture);
      if (predictions.size() > 0) {
          Prediction prediction = (Prediction) predictions.get(0);
          if (prediction.score > 1.0) {
              Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
              for(int i=0;i<predictions.size();i++)
                Log.v(TAG, "prediction " + predictions.get(i).name +
                    " - score = " + predictions.get(i).score);
          }
      }
  }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/main.xml -->
<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="Draw gestures and I'll guess what they are"
    />
    
<android.gesture.GestureOverlayView
    android:id="@+id/gestureOverlay"
    android:layout_width="fill_parent"  android:layout_height="fill_parent"
    android:gestureStrokeType="multiple"  android:fadeOffset="1000"
    />

</LinearLayout>

List Gesture libray information

   

        
package app.test;

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.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.GestureStore;
import android.gesture.Prediction;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class Test extends Activity implements OnGesturePerformedListener {
    private static final String TAG = "Gesture Revealer";
  GestureLibrary gestureLib = null;

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

//        gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures_letters);
        gestureLib = GestureLibraries.fromFile("/sdcard/gestures");
        gestureLib.setOrientationStyle(GestureStore.ORIENTATION_INVARIANT);
        gestureLib.setSequenceType(GestureStore.SEQUENCE_INVARIANT);

        if (!gestureLib.load()) {
            Toast.makeText(this, "Could not load /sdcard/gestures", Toast.LENGTH_SHORT).show();
            finish();
        }
        Log.v(TAG, "  Orientation style: " + gestureLib.getOrientationStyle());
        Log.v(TAG, "  Sequence type: " + gestureLib.getSequenceType());
        for( String gestureName : gestureLib.getGestureEntries() ) {
          Log.v(TAG, "For gesture " + gestureName);
          int i = 1;
            for( Gesture gesture : gestureLib.getGestures(gestureName) ) {
              Log.v(TAG, "    " + i + ": ID: " + gesture.getID());
              Log.v(TAG, "    " + i + ": Strokes count: " + gesture.getStrokesCount());
              Log.v(TAG, "    " + i + ": Stroke length: " + gesture.getLength());
              i++;
            }
        }

        GestureOverlayView gestureView = (GestureOverlayView) findViewById(R.id.gestureOverlay);
        gestureView.addOnGesturePerformedListener(this);
        gestureView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
    }

  public void onGesturePerformed(GestureOverlayView view, Gesture gesture) {
      ArrayList<Prediction> predictions = gestureLib.recognize(gesture);
      if (predictions.size() > 0) {
          Prediction prediction = (Prediction) predictions.get(0);
          if (prediction.score > 1.0) {
              Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
              for(int i=0;i<predictions.size();i++)
                Log.v(TAG, "prediction " + predictions.get(i).name +
                    " - score = " + predictions.get(i).score);
          }
      }
  }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/main.xml -->
<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="Draw gestures and I'll guess what they are"
    />
    
<android.gesture.GestureOverlayView
    android:id="@+id/gestureOverlay"
    android:layout_width="fill_parent"  android:layout_height="fill_parent"
    android:gestureStrokeType="multiple"  android:fadeOffset="1000"
    />

</LinearLayout>

Gesture Recognition

   
//package backend.snippets;

import java.util.ArrayList;
import android.gesture.Gesture;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.Prediction;
import android.widget.EditText;
import android.widget.TabHost;
import android.widget.Toast;

public class GestureRecognition {
  

  public void gestureReco(GestureOverlayView overlay, Gesture gesture, GestureLibrary mLibrary, TabHost tabs, App a, EditText carColor)
  {
    ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
    Toast.makeText(a, null, Toast.LENGTH_SHORT).cancel();
    if (predictions.size() > 0) {
      Prediction prediction = predictions.get(0);
      if (prediction.score > 1.0) {
        if(prediction.name.equalsIgnoreCase("right"))
        {
          tabs.setCurrentTab(tabs.getCurrentTab()+1);
        }
        else if(prediction.name.equalsIgnoreCase("left"))
        {
          tabs.setCurrentTab(tabs.getCurrentTab()-1);
        }
        else
        {
          carColor.setText(prediction.name);
          Toast.makeText(a, prediction.name, Toast.LENGTH_SHORT).show();
        }
      }      
    }
  }
  
}