Android Gusture 手势识别小案例
Step1: 生成一个Android Gusture Builder程序用于画Gusture然后存储起来用于其它的项目
首先导入 android SDK \android-sdk-windows\samples\android-8\ 目录下的GestureBuilder项目,用于生成Gusture类库
导入过程中要加入几个文件才能导入到Eclipse中,如下图所示: 这几个文件可以从任意android项目中copy
.classpath .project default.properties 3个文件
导入之后生成项目如下图所示: 将该项目安装到模拟器中,如下图所示:
step2:应用此程序生成我们需要的手势,点击 Add gesture按钮添加手势,随便添加几个手势之后
然后会在sdcard中生成一个gusture文件 如图所示
step2:将此gusture文件导出到桌面,然后再复制到新建的项目中去
step3:新建项目Gusture,并将刚才的gusture文件导入到/res/raw目录下 ,如下图所示
step4: 设计应用的UI界面,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"> <android.gesture.GestureOverlayView android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:id="@+id/gesture" android:gestureStrokeType="multiple"/><!-- 多笔手势 --> <!-- android:layout_weight="0" 值越低越先赋值 所以先对Button赋值再对android.gesture.GestureOverlayView赋值 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" android:text="@string/recognize" android:onClick="findGesture" /> </LinearLayout>
string.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, MainActivity!</string> <string name="app_name">手势识别</string> <string name="notfind">手势不匹配</string> <string name="notfull">手势匹配度太低</string> <string name="recognize">识别</string> </resources>
step5:MainActivity.java
package cn.roco.gesture; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.gesture.Gesture; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.Prediction; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { private static final String TAG="MainActivity"; private GestureLibrary library; private Gesture mygesture; private GestureOverlayView gestureOverlayView ; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /** 根据放入到res/raw/目录下的gestures文件生成GestureLibrary手势库 */ library = GestureLibraries.fromRawResource(this, R.raw.gestures); /**加载手势库*/ library.load(); gestureOverlayView = (GestureOverlayView) this .findViewById(R.id.gesture); /**只能监听单笔手势*/ /* gestureOverlayView .addOnGesturePerformedListener(new MyGesturePerformedListener());*/ /**可以监听单笔手势也可以监听多笔手势*/ gestureOverlayView.addOnGestureListener(new MyGestureListener()); } /** * 处理按钮响应的方法 * 点击识别按钮 开始识别手势 */ public void findGesture(View view){ recognizeGesture(mygesture); //清除画出的手势 gestureOverlayView.clear(true); } private final class MyGestureListener implements android.gesture.GestureOverlayView.OnGestureListener{ @Override public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) { Log.i(TAG, "onGestureStarted"); } @Override public void onGesture(GestureOverlayView overlay, MotionEvent event) { Log.i(TAG, "onGesture"); } @Override public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) { Log.i(TAG, "onGestureEnded"); /**取得用户最后画完后的手势*/ mygesture=overlay.getGesture(); } @Override public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) { Log.i(TAG, "onGestureCancelled"); } } /** * 用户绘制完手势后响应 */ private final class MyGesturePerformedListener implements android.gesture.GestureOverlayView.OnGesturePerformedListener { @Override public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { recognizeGesture(gesture); } } /**识别手势*/ private void recognizeGesture(Gesture gesture) { /** * 从手势库中查询匹配的内容, 匹配结果可能包含多个相似的内容, * 匹配度高的结果放在最前面 */ ArrayList<Prediction> predictions = library.recognize(gesture); if (!predictions.isEmpty()) { Prediction prediction=predictions.get(0); if (prediction.score>=6) { //匹配度大于等于60% if ("ouyang".equals(prediction.name)) { /**调用手机拨号程序*/ Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:15245474568")); startActivity(intent); }else if("close".equals(prediction.name)){ finish();//关闭Activity 会引发onDestory方法 } }else{ //手势匹配度太低 Toast.makeText(getApplicationContext(), R.string.notfull, 1) .show(); } } else { //不匹配 Toast.makeText(getApplicationContext(), R.string.notfind, 1) .show(); } } @Override protected void onDestroy() { super.onDestroy(); /** 杀掉本应用的进程 * 第一种方法:首先获取当前进程的id,如何杀死该进程 */ android.os.Process.killProcess(android.os.Process.myPid());//关闭应用 /** * 关闭应用还有2种方法 * * 第二种方法:终止当前正在运行的Java虚拟机,导致程序终止 * System.exit(0); * * * 第三种方法:强制关闭与该包有关联的一切执行 * android.app.ActivityManager manager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); manager.restartPackage(getPackageName()); 还要添加权限才行 <uses-permission android:name="android.permission.CALL_PHONE"/> * */ } }
step6:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.roco.gesture" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <!-- 拨打电话的权限 --> <uses-permission android:name="android.permission.CALL_PHONE"/> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" 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>
step7:将项目部署到模拟器中,如果所示界面:
然后画手势 点击“识别”按钮进行识别 上面的时候一点击 就退出了此应用
然后画手势 点击“识别”按钮进行识别 就激活了拨号程序进行拨号
然后画手势 点击“识别”按钮进行识别 显示匹配度太低
附注:自己写一个添加手势的应用
AddGesture.java
package cn.roco.gesture; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.gesture.Gesture; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.GestureOverlayView.OnGesturePerformedListener; import android.graphics.Bitmap; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; /** * 添加手势 */ public class AddGesture extends Activity { EditText editText; GestureOverlayView gestureOverlayView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.addgesture); // 获取文本编辑器 editText = (EditText) findViewById(R.id.gesture_name); // 获取手势编辑视图 gestureOverlayView = (GestureOverlayView) findViewById(R.id.gesture); // 设置手势的绘制颜色 gestureOverlayView.setGestureColor(Color.RED); // 设置手势的绘制宽度 gestureOverlayView.setGestureStrokeWidth(4); // 为 gesture的手势完成事件绑定事件监听器 gestureOverlayView .addOnGesturePerformedListener(new OnGesturePerformedListener() { @Override public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture) { // 加载save.xml界面布局代表的视图 View saveDialog = getLayoutInflater().inflate( R.layout.save, null); // 获取 saveDialog里的ImageView组件 ImageView imageView = (ImageView) saveDialog .findViewById(R.id.show); // 获取 saveDialog里的 EditText组件 final EditText gestureName = (EditText) saveDialog .findViewById(R.id.gesture_name); // 根据 Gesture包含的手势创建一个位图 Bitmap bitmap = gesture.toBitmap(128, 128, 10, 0xFFFF0000); imageView.setImageBitmap(bitmap); // 使用对话框显示saveDialog组件 new AlertDialog.Builder(AddGesture.this) .setView(saveDialog) .setPositiveButton("保存", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 获取指定的文件对应的手势库 GestureLibrary gestureLibrary = GestureLibraries .fromFile("/sdcard/gestures"); // 添加手势 gestureLibrary.addGesture(gestureName .getText().toString(), gesture); // 保存手势库 gestureLibrary.save(); Toast.makeText(getApplicationContext(), "保存成功", 1).show(); } }) .setNegativeButton("取消", null) .show(); } }); } }
addgesture.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:text="请在下面屏幕上绘制手势" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <!-- 使用手势绘制组件 --> <android.gesture.GestureOverlayView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:id="@+id/gesture" android:gestureStrokeType="multiple" /><!-- 多笔手势 --> </LinearLayout>
save.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"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:text="请输入保存的手势名称" android:layout_marginRight="8dip" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <!-- 定义一个文本框来让用户输入手势名 --> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/gesture_name" /> </LinearLayout> <ImageView android:id="@+id/show" android:layout_marginTop="10dp" android:layout_width="128dp" android:layout_height="128dp " /> </LinearLayout>