북극곰의 개발일기

사용자 제스처 인식시키기





posted by purplebeen on Sat Feb 03 2018 22:14:38 GMT+0900 (KST) in Android


사용자 제스처를 인식시키기 전에 먼저 gesture 파일을 생성시켜야 한다.

안드로이드 에뮬레이터 안에 있는 gesture Builder App을 이용하여 제스처를 만들어야 한다.

이제 그러면 adb를 통해 에뮬레이터 sdCard에 저장된 gesture 파일을 추출 시켜야 한다.

SDK가 설치된 경로 안에 있는 platform-tools로 들어가서 adb를 실행시킨다.

adb devices 를 통해 에뮬레이터의 번호를 확인한다.

adb를 이용해 /sdcard/gestures 를 가져온다.

res에 raw라는 폴더를 만들고 그 폴더 안에 gestures 파일을 복사한다.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1">

    <android.gesture.GestureOverlayView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/gOverlay"
        android:layout_gravity="center_horizontal"
        android:gestureColor="#00FF00"
        android:uncertainGestureColor="#00FF00">

</android.gesture.GestureOverlayView>
</LinearLayout>

기본 Layout으로 Linear Layout을 선정해주었고,

최대한 차지하도록 width와 height는 match_parent로 설정하였고,

Layout의 방향성은 vertical 즉 세로 형으로 설정하였다.

또한 Gesture를 받아오기 위해 android.gesture.GestureOverlayView 레이아웃을 선언하였고,

이것의 id를 gOverLay로 선언하였다. 부모 레이아웃(여기서는 LinearLayout) 의 옵션을 고려하여 가로 기준의 중앙에 맞추어 위치하도록 선언해 놓았다.

gestureColor를 사용하여 정상적인 gesture를 입력할때 컬러를 설정하였고,

uncertainGestureColor를 사용하여 정의되지 않은 제스처를 입력할때의 컬러를 설정하였다.

package com.example.baehy.customgestures;

import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.Prediction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements
 GestureOverlayView.OnGesturePerformedListener {
    private GestureLibrary gLibrary;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
        if(!gLibrary.load()) {
            finish();
        }
        GestureOverlayView gOverlayView = (GestureOverlayView) findViewById(R.id.gOverlay);
        gOverlayView.addOnGesturePerformedListener(this);
    }

    @Override
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
        ArrayList<Prediction> predictions = gLibrary.recognize(gesture);

        if(predictions.size() > 0 && predictions.get(0).score > 1.0) {
            String action = predictions.get(0).name;
            Toast.makeText(this, action, Toast.LENGTH_SHORT).show();
        }
    }
}

gLibrary를 이용하여 gesture 파일을 불러왔고, gestures 파일을 불러오지 못햇으면 끝내도록 설정했다.

Activity에서 gOverView Layout을 접근할 수 있도록 onCreate 메소드 에서 선언해주었다.

GestureOverlayView 객체에서 안드로이드 런타임에 의해 제스처가 감지되면 onGesturePerformed 메소드가 호출되고 ,

이때 인자값으로 OverlayView 객체의 참조와 Gesture 타입 객체가 함게 전달된다.

Gesture객체가 gLibrary 인스턴스의 recognize() 메소드로 전달되고, 이 과정에서 저장된 Cujstom Gesture와 일치하는지를 비교한다.

비교 작업이 끝나면 ArrayList 객체를 반환하고, ArrayList에는 비교연산의 결과가 담긴 Predection 객체가 담긴다.

이때 저장된 prediction 객체 중에서 0번째(가장 일치하는 값)의 예측 점수가 1.0이면

어떤 gesture인지 이름을 받아와서 action이라는 String에 저장하고, 이를 토스트로 띄워준다.