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(); } } } } }