Android Gusture 手勢識別小案例

jopen 11年前發布 | 40K 次閱讀 Android Android開發 移動開發

Step1: 生成一個Android Gusture Builder程序用于畫Gusture然后存儲起來用于其它的項目

 

首先導入  android SDK \android-sdk-windows\samples\android-8\   目錄下的GestureBuilder項目,用于生成Gusture類庫

導入過程中要加入幾個文件才能導入到Eclipse中,如下圖所示: 這幾個文件可以從任意android項目中copy

.classpath    .project   default.properties 3個文件

 

導入之后生成項目如下圖所示:                                                                                                              將該項目安裝到模擬器中,如下圖所示:

 Android Gusture 手勢識別小案例                                                             Android Gusture 手勢識別小案例

 

step2:應用此程序生成我們需要的手勢,點擊 Add gesture按鈕添加手勢,隨便添加幾個手勢之后

  Android Gusture 手勢識別小案例 然后會在sdcard中生成一個gusture文件  如圖所示

 Android Gusture 手勢識別小案例

 

 

step2:將此gusture文件導出到桌面,然后再復制到新建的項目中去

step3:新建項目Gusture,并將剛才的gusture文件導入到/res/raw目錄下 ,如下圖所示

 Android Gusture 手勢識別小案例

 

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:將項目部署到模擬器中,如果所示界面:

 Android Gusture 手勢識別小案例              Android Gusture 手勢識別小案例

然后畫手勢 點擊“識別”按鈕進行識別   上面的時候一點擊  就退出了此應用

 


 

 Android Gusture 手勢識別小案例                              Android Gusture 手勢識別小案例  

 然后畫手勢 點擊“識別”按鈕進行識別 就激活了撥號程序進行撥號          

 

 Android Gusture 手勢識別小案例                           Android Gusture 手勢識別小案例

然后畫手勢 點擊“識別”按鈕進行識別 顯示匹配度太低

 

 

 

 

附注:自己寫一個添加手勢的應用

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>


       Android Gusture 手勢識別小案例                                     Android Gusture 手勢識別小案例

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!