package com.example.gesturetestdemo;
/*
* 手势识别
* 1.在GestureOverlayView中指定了一个android:gestureStrokeType参数,该参数控制手势是否需要多一笔完成
* 大部分时候,一个手势只要一笔就可以完成,此时可将该参数设为single,如果该手势需要多笔来完成,则将该参数
* 设为multiple
* Android除了提供手势检测之外,还允许应用 程序把用户手势(多个持续的触摸事件在屏幕上形成特定的形状)添加
* 到指定文件中,以备以后使用,如果程序需要,当用户下次画出该手势时,系统将可识别该手势
* Android使用GestureLibrary来代表手势库,并提供GestureLibraries工具类来创建手势库,GestureLibraries
* 提供了如下4个静态方法从不同位置加载手势库
* static GestureLibrary fromFile(String path):从path代表的文件中加载手势库
* static GestureLibrary fromFile(File path):从path代表的文件中加载手势库
* static GestureLibrary fromPirvateFile(Context context,String name);从指定应用程序的数据文件夹中name文件中加载手势库
* static GestureLibrary fromRawResoource(Context context,int resourceId):从resourceId所代表的资源中加载手势库
* 一旦在程序中获得了GestureLibrary对象之后,该对象提供如下方法来添加手势、识别手势
* void addGesture(String entryName,Gesture gesture):添加一个名为entryName的手势
* Set<String>getGestureEntries();获取该手势库中所有手势的名称
* ArrayList<Gesture>getGestures(String entryName):获取entryName名称对应的全部手势
* ArrayList<Prediction>recognize(Gesture gesture):从当前手势库中识别与gesture匹配的全部手势
* void removeEntry(String entryName):删除手势库中entryName对应的手势
* void removeGesture(String entryName,Gesture gesture):删除手势库中entryName,gesture对应的手势
* boolean save():当向手势库中添加手势或从中删除手势后调用该方法保存手势库
* Android除了提供GestureLibraries、GestureLibrary来管理手势之外,还提供一个专门的手势编辑组件:GestureOverlayView,该
* 组件就像一个“绘图组件”,只是用户在组件上绘制的不是图形,而是手势
* 为了监听GestureOverlayView组件上的手势时间,Android为GestureOverlayView提供了OnGrestureListener、OnGesturePerformedListener/
*OnGesturingListener三个监听器接口,这些监听器所包含的方法分别用于响应手势事件开始、结束、完成、取消等事件,开发者可
*根据实际需要来选择不同的监听器--一般来说,OnGesturePerformedListener是最常用的监听器,它可用于在手势事件完成时提供响应
*本例中需要读写SD卡,所以需添加权限 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
*
*/
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
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.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
GestureOverlayView gestureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*获取手势编辑视图*/
gestureView=(GestureOverlayView) findViewById(R.id.gesture);
/*设置手势的绘制颜色*/
gestureView.setGestureColor(Color.BLUE);
/*设置手势绘制时的宽度*/
gestureView.setGestureStrokeWidth(5);
/*获取指定文件对应的库*/
final GestureLibrary gestureLib=GestureLibraries.fromFile("/mnt/sdcard/mygestures");
/*为gesture的手势完成事件绑定事件监听器*/
gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener() {
@Override
public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture) {
// TODO Auto-generated method stub
/*加载save.xml界面布局代表的视图*/
View saveDialog=getLayoutInflater().inflate(R.layout.save,null);
/*加载save上的ImageView组件*/
ImageView imageView=(ImageView) saveDialog.findViewById(R.id.show);
/*加载save里的gesture_name的组件*/
final EditText gestureName=(EditText) saveDialog.findViewById(R.id.gesture_name);
/*根据gesture包含的手势创建一个位图*/
Bitmap bitmap=gesture.toBitmap(128,128,10,Color.argb(255,0,0,255));
/*设置ImageView*/
imageView.setImageBitmap(bitmap);
/*弹出saveDialog对话框*/
new AlertDialog.Builder(MainActivity.this)
.setView(saveDialog)
.setPositiveButton("保存",new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
/*添加手势*/
gestureLib.addGesture(gestureName.getText().toString(), gesture);
/*保存手势库*/
gestureLib.save();
}
})
.setNegativeButton("取消",null)
.show();
}
});
}
/*点击TextView事件响应*/
public void loadGesture(View v){
/*启动匹配手势界面*/
Intent intent=new Intent(MainActivity.this,LoadGesture.class);
startActivity(intent);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="请在屏幕上绘制手势"
android:clickable="true"
android:onClick="loadGesture"
android:id="@+id/t1"/>
<android.gesture.GestureOverlayView
android:id="@+id/gesture"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gestureStrokeType="multiple"></android.gesture.GestureOverlayView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:text="手势名称:"/>
<EditText
android:id="@+id/gesture_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<ImageView
android:id="@+id/show"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginTop="10dp"/>
</LinearLayout>
package com.example.gesturetestdemo;
import java.util.ArrayList;
import java.util.Set;
import android.app.Activity;
import android.app.AlertDialog;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Toast;
public class LoadGesture extends Activity {
GestureOverlayView gestureView;
GestureLibrary gestureLib;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*获取手势编辑视图*/
gestureView=(GestureOverlayView) findViewById(R.id.gesture);
/*加载手势库*/
gestureLib=GestureLibraries.fromFile("/mnt/sdcard/mygestures");
if(gestureLib.load()){
Toast.makeText(LoadGesture.this, "手势文件装载成功!",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(LoadGesture.this, "手势文件装载失败", Toast.LENGTH_SHORT).show();
}
/*获取手势库中所有手势的名字,测试用*/
Set<String> lib=gestureLib.getGestureEntries();
for(String str:lib){
System.out.println(str);
}
/*手势完成事件监听器*/
gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener() {
@Override
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
// TODO Auto-generated method stub
/*识别绘制的手势*/
ArrayList<Prediction> predictions=gestureLib.recognize(gesture);
ArrayList<String> result=new ArrayList<String>();
/*遍历所有找到的Prediction对象*/
for(Prediction pred:predictions){
/*只有相似度大于2.0的手势才会被输出*/
if(pred.score>2.0){
result.add("与手势【"+pred.name+"】相似度"+pred.score);
}
}
if(result.size()>0){
ArrayAdapter<Object> adapter=new ArrayAdapter<Object>(LoadGesture.this,
android.R.layout.simple_dropdown_item_1line,result.toArray());
/*使用一个带list的对话框来显示所有匹配的手势*/
new AlertDialog.Builder(LoadGesture.this)
.setAdapter(adapter, null)
.setPositiveButton("确定",null)
.show();
}else{
Toast.makeText(LoadGesture.this, "无法找到匹配的手势", Toast.LENGTH_SHORT).show();
}
}
});
}
}