Android+手勢識別詳解

來源:互聯網
上載者:User

今天就來把以前的學習文章與經驗簡單總結中出來吧,在這裡我就直接把代碼貼下來了,希望能給初學者做最佳的學習參考,也希望有更多的開發人員來加入ANDROIDTeam Dev,參與更多的創新方式的開發,好了,今天我就簡單的講解一個關於手勢識別的最基礎也是最需要去掌握的一個技術節點,因為他能給我們在開發中可能獲得最新的使用者體驗效果,如利用手勢識別,你只需要簡單的一個手勢操作就可能去完成你想要完成的某件可能比較複雜的事情,如通過一個手勢來實現打電話,而並不需要去找你所需要的電話號碼這個比較麻煩的過程了,如你可以通過一個手勢識別直接來登入到某個你事先設定好的一個應用,或者登入到某個網站,設定是去實現你想要對某個應用做出某些動作的操作響應,然而我們要做到這些都不能忽視我們首先需要做的是你必須首先得完成一個最簡單的手勢操作,世界上莫過於學習程式最難的就是寫第一個Hello,World!程式並列印出來,當然如果你那樣做到了,那也才是對其剛剛開始的節奏,再下來我們還得加倍去學習並完全知道它為什麼會實現這樣的效果,出了能完成這些最基本的操作還有別的嗎,是不是可以在此基礎上加些額外的思考呢,OK,為了達到這個目的,我們先來完成一個最基本的手勢識別吧,主要實現的功能有通過一個手勢來實現撥打指定某個人的電話與再通過一個手勢來實現退出的功能,在這裡我就結合SDK下的一個手勢案例直接來操作實現的過程,建立手勢庫的過程,自己去看D:/toolss/android-sdk-windows/samples/android-8/GestureBuilder這個手勢案例吧,好了,我先使用SDK下的GestureBuilder來產生兩個手勢放於庫/mnt/sdcard/LOST.DIR/gestures檔案下,然後我們把gestures檔案拷貝到建立項目下一個建立的:/res/raw/gestures下,然後在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:id="@+id/gestures"
  android:layout_width="fill_parent"
  android:layout_height="0dip"
  android:layout_weight="1.0"
  android:gestureStrokeType="multiple"
  />
</LinearLayout>

其配置支字元參數為strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MainActivity!</string>
    <string name="app_name">手勢識別2</string>
    <string name="norecohnize">不能識別該手勢</string>
    <string name="nopediction">手勢識別百分率太低,請重新輸入</string>
</resources>
src下的原始碼為:

package com.jsd.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.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity {
 private GestureLibrary libraray;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        libraray = GestureLibraries.fromRawResource(this, R.raw.gestures);//載入手勢庫對象
        libraray.load();//載入手勢庫
        GestureOverlayView overlayView = (GestureOverlayView)this.findViewById(R.id.gestures);
        
        overlayView.addOnGesturePerformedListener(new GestureListener());
    }
   
    private final class GestureListener implements OnGesturePerformedListener{

  @Override
  public void onGesturePerformed(GestureOverlayView overlay,
    Gesture gesture) {
   // TODO Auto-generated method stub
   ArrayList<Prediction> predictions = libraray.recognize(gesture);//識別使用者輸入的手勢是否存在手勢庫中
   if(!predictions.isEmpty()){
    Prediction prediction = predictions.get(0);//得到匹配的手勢
    if(prediction.score > 3){
     if("close".equals(prediction.name)){
      //關閉應用
      finish();
     }else if("phone".equals(prediction.name)){
      //指定某個人打電話
      Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:18601159149"));
      startActivity(intent);
      
     }
    }else{
     Toast.makeText(MainActivity.this, R.string.nopediction, 1).show();
    }
   }else{
    Toast.makeText(MainActivity.this, R.string.norecohnize, 1).show();
   }
  }
     
    }
    /**
     * 在這個方法中來調用其關閉
     * 關閉應用的方法有三種:
     * 1.擷取其進程ID來殺死該進程:推介使用:android.process.killProcess(android.os.Process myPid());
     * 2.終止正在啟動並執行JAVA虛擬機器,從而導致程式終止:System.exist(0);
     * 3.強制關閉與該報有關的一切執行:AcitvityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);manager.restartPackage(getPackageName());<uses-permission android:name="android.permission.RESTART_PACKAGES"/>
     */
    private void onDstroy() {
  // TODO Auto-generated method stu
     android.os.Process.killProcess(android.os.Process.myPid());//當ACTIVITY被摧毀的時候我們就把應用給殺死
     
 }
}

以上就這個應用的所有代碼,當然如果有對代碼不太理解的話,請下載原始碼,上面是我直接粘貼的,那就把下面自己按思路寫的代碼與注釋一起粘貼下來吧,希望初學者也能根據自己的思路去寫出自己的注釋效果與理解收穫:

手勢識別:
1.什麼是手勢識別技術:如一個人使用一個手指在螢幕上畫上某些符號來代表的說需要操作的某項業務,如畫個圈代表向

某個人打電話等.
2.建立手勢哭:類似於資料庫,即一些手勢符號的資料存放區.看一個例子:sdk/samples/android-8/GestureBuilder,建立好

的手勢庫會存在SD卡上面,預設的檔案名稱為:gestures.
3.根據使用者輸入的手勢後進行判斷,如果其資料庫存在相應的手勢就返回出來,
4.在res下面建立一個專門用來存放靜態檔案的目錄raw,把手勢庫檔案拷貝其目錄檔案下,當然它也會在gen目錄下的R類

中產生關於該檔案的一個常量引用
5.然後在main.xml中寫入:
 <android.gesture.GestureOverlayView
  android:id="@+id/gestures"
  android:layout_width="fill_parent"
  android:layout_height="0dip"
  android:layout_weight="1.0"/>
通過以上的控制項,使用者就會通過手指在手機上畫對應符號出來,然後就需要在代碼進行引用了:GestureOverlayView

overlayView = (GestureOverlayView)this.findViewById(R.id.gestures);
6.添加一個手勢繪製完之後的監聽事件:overlayView.addOnGesturePerformedListener(new GestureListener());
7.提供一個類來對手勢監聽實現介面:private final class GestureListener implements

OnGesturePerformedListener{
 //當使用者畫完之後就會給使用者一個參數傳入其方法
 public void onGesturePerformed(GestureOverlayView overlay,Gesture gesture){//實現介面的方法
  //下面就需要判斷手勢是否存在資料庫中與其精度是否達到要求,這時需要載入手勢庫這個類:
  ArrayList<Prediction> prediction = libraray.recognize(gesture);//識別使用者輸入的手勢是否存

在手勢庫中,並返回所有跟這個手勢相似的手勢,並且它會把相似性最高的手勢放在最前面,也就是說在這個機會中的第一

個元素相似性是最高的,現在只需要相似性最高的手勢即可:
  if(!predictions.isEmpty()){
   Prediction prediction = predictions.get(0);//得到最匹配的手勢
   if(prediction.score){//判斷相似性:0~10  >40%即可
     if("close".equals(prediction.name)){
      //關閉應用:1.首先擷取當前進程ID,然後殺死該進程(建議使

用):android.Process.killProcess(android.os.Process myPid());2.終止當前正在啟動並執行Java虛擬機器,導致程式終

止:System.exit(0);3.強制關閉與該包有關聯的一切執行:ActivityManager manager = (ActivityManager)

getSystemService(Context.ACTIVITY_SERVICE);manager.restartPackage(getPackageName());<uses-permission

android:name="android.permission.RESTART_PACKAGERS"/>;這裡需要注意,我們不能在這裡直接使用這三種方法中的一

種,如果這樣的話ACTIVITY的ONDESTORY()方法就無法調用以至於無法正常關閉,但是我們可以在這裡點調用finish()方法

來讓其ACTIVITY先正常關閉,然後在觸發ONDESTORY()裡進行調用
      
     }else if("phone".equals(prediction.name)){
      //指定一個人打電話
     }
   }else{
    Toast.makeText(MainActivity.this,R.string/nopediction,1).show;
   }
  }else{
   Toast.makeText(MainActivity.this,R.string.norecognize,1).show;
  }
 }
}
問題:大多數手勢都是一筆完成,然而需求可能需要兩筆或者以上來完成,這時可以使用gestureStrokeType屬性進行設

置:android:gestureStrokeType="multiple"

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.