手势识别
手势识别步骤:
第一步:建立手势库
使用SDK自带例子GestureBuilder建立手势库(位置:android-sdk-windows\samples\android-8\GestureBuilder)。使用GestureBuilder之前,你需要恢复其到开发环境,然后进行编绎并部署到手机上。此时,就可以使用GestureBuilder建立手势库,生成的手势库文件在SCDard上,默认文件名称为:gestures
第二步:在应用中加载手势库文件,然后开发手势识别代码。
把手势库文件gestures文件拷贝到项目的res/raw目录下。然后在布局文件中添加用于手势绘制的View:
1 <android.gesture.GestureOverlayView 手势绘制的控制 2 3 android:id="@+id/gestures" 4 5 android:layout_width="fill_parent“ android:layout_height="0dip" 6 7 android:layout_weight="1.0" />
为View添加手势监听事件:gestureOverlayView.addOnGesturePerformedListener();
得到手势库:mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
加载手势库:mLibrary.load();
List<Prediction> predictions = mLibrary.recognize(gesture);//从手势库中查询匹配的内容,匹配的结果可能包括多个相似的内容,匹配度高的结果放在最前面
大多数情况下,手势都是通过一笔完成。然而有一些特别的需求就需要通过多个笔画来实现,这时可以使用gestureStrokeType属性进行设置:android:gestureStrokeType="multiple"
手势识别代码:
清单文件
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:background="@android:color/black" 5 android:orientation="vertical" > 6 7 <android.gesture.GestureOverlayView 8 android:id="@+id/gov" 9 android:layout_width="match_parent" 10 android:layout_height="0dp" 11 android:layout_weight="1" 12 android:gestureStrokeType="multiple" /> 13 <!-- android:gestureStrokeType="multiple" 默认的是单笔手势,添加该属性后多笔手势识别 --> 14 15 <LinearLayout 16 android:layout_width="match_parent" 17 android:layout_height="wrap_content" 18 android:orientation="horizontal" > 19 20 <Button 21 android:layout_width="0dp" 22 android:layout_height="wrap_content" 23 android:layout_weight="1" 24 android:onClick="ok" 25 android:text="确定" /> 26 27 <Button 28 android:layout_width="0dp" 29 android:layout_height="wrap_content" 30 android:layout_weight="1" 31 android:onClick="cancel" 32 android:text="取消" /> 33 </LinearLayout> 34 35 </LinearLayout>
代码:
1 package com.android.hzy.gesture; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.content.Intent; 7 import android.gesture.Gesture; 8 import android.gesture.GestureLibraries; 9 import android.gesture.GestureLibrary; 10 import android.gesture.GestureOverlayView; 11 import android.gesture.GestureOverlayView.OnGestureListener; 12 import android.gesture.GestureOverlayView.OnGesturePerformedListener; 13 import android.gesture.Prediction; 14 import android.net.Uri; 15 import android.os.Bundle; 16 import android.util.Log; 17 import android.view.MotionEvent; 18 import android.view.View; 19 import android.widget.Toast; 20 21 public class MainActivity extends Activity { 22 23 private GestureOverlayView gov; 24 private GestureLibrary library; 25 // 定义一个全局的手势 26 private Gesture gesture; 27 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(R.layout.activity_main); 32 33 gov = (GestureOverlayView) findViewById(R.id.gov); 34 // 添加手势执行监听 35 // gov.addOnGesturePerformedListener(new MyOnGesturePerformedListener()); 该监听方法只针对单笔手势 36 gov.addOnGestureListener(new MyOnGestureListener());// 多笔手势监听方法 37 38 // 加载手势库 39 library = GestureLibraries.fromRawResource(this, R.raw.gestures); 40 library.load(); // 加载手势库 41 42 } 43 44 /** 45 * 多笔手势监听 46 */ 47 private final class MyOnGestureListener implements OnGestureListener{ 48 49 /**************onGestureStarted 手触摸上去时调用此方法*************************/ 50 @Override 51 public void onGestureStarted(GestureOverlayView overlay, 52 MotionEvent event) { 53 // TODO Auto-generated method stub 54 Log.i("i", "onGestureStarted() "); 55 56 } 57 58 /************onGesture 开始绘制时调用此方法(手在上面滑动)************/ 59 @Override 60 public void onGesture(GestureOverlayView overlay, MotionEvent event) { 61 // TODO Auto-generated method stub 62 Log.i("i", "onGesture() "); 63 } 64 65 /**************onGestureEnded 手离开屏幕后调用此方法**************************/ 66 @Override 67 public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) { 68 // TODO Auto-generated method stub 69 Log.i("i", "onGestureEnded() "); 70 71 gesture = overlay.getGesture();// 获取当前的手势 72 } 73 74 @Override 75 public void onGestureCancelled(GestureOverlayView overlay, 76 MotionEvent event) { 77 // TODO Auto-generated method stub 78 Log.i("i", "onGestureCancelled() "); 79 } 80 81 } 82 83 /** 84 * 手势执行监听(单笔手势) 85 */ 86 private final class MyOnGesturePerformedListener implements 87 OnGesturePerformedListener { 88 /* 89 * overlay :当前的控件 gesture :当前的绘制手势 90 */ 91 @Override 92 public void onGesturePerformed(GestureOverlayView overlay, 93 Gesture gesture) { 94 recognize(gesture); 95 } 96 97 } 98 99 public void ok(View v){ 100 recognize(gesture); 101 // 清空画的多笔手势 102 gov.clear(true); 103 } 104 105 public void cancel(View v){ 106 gov.clear(true); 107 } 108 109 /** 110 * 识别手势 111 * @param gesture 112 */ 113 private void recognize(Gesture gesture) { 114 // 从手势库去识别手势 115 ArrayList<Prediction> predictions = library.recognize(gesture); 116 if (predictions.isEmpty()) { 117 Toast.makeText(getApplicationContext(), "手势不存在", 0).show(); 118 } else { 119 // 得到最匹配的手势 120 Prediction prediction = predictions.get(0); 121 double score = prediction.score; // 0~10 122 if (score >= 6) { // 60%的匹配度 123 String name = prediction.name; // 手势的名字 124 if (name.equals("call")) { 125 // 打电话 126 Intent intent = new Intent(Intent.ACTION_CALL, 127 Uri.parse("tel:" + 5556)); 128 startActivity(intent); 129 } else if(name.equals("close")){ 130 // 关闭应用程序 131 android.os.Process.killProcess(android.os.Process.myPid()); 132 } 133 } else { 134 Toast.makeText(getApplicationContext(), "匹配度太低", 0).show(); 135 } 136 } 137 } 138 }