AndroidOS1.6以上から使えるようになった android.gesture APIを試してみました。
Googleが提供しているSampleがあります。
ジェスチャーライブラリ作成
事前に使用するジェスチャーを登録しておく必要があります。
ジェスチャーを登録する方法は以下の二種類となります。
- ADVでSDカードありで作成し、アプリ内にあるGestures Builderにてジェスチャー登録。
- android-sdk/samples/android-5(以上)/GestureBuilder/ をビルドしてSDカードのある端末にインストール、端末上にてジェスチャー登録。
ジェスチャー登録後にデバイスのsdcard直下にgesturesが作成されているのでPC側にコピーする。
なお、どちらの方法でも構いませんが、端末上でジェスチャー登録する方が描きやすいのでオススメです。
アプリに取り込む
プロジェクトを作成し、/res/raw/ 以下にgesturesを配置する。
ジェスチャーを読み込む
Googleが提供しているSampleとほぼ変わりませんが、以下のように読み込めます。
public class MainActivity extends Activity implements OnGesturePerformedListener { private GestureLibrary mLibrary; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures); if (!mLibrary.load()) { finish(); } GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures); gestures.addOnGesturePerformedListener(this); } // 描かれた後に呼ばれる public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList<Prediction> predictions = mLibrary.recognize(gesture); if (predictions.size() > 0) { Prediction prediction = predictions.get(0); // 描かれた絵と登録した絵の一致度(スコア)が一番高い if (prediction.score > 1.0) { if (gestureName.equals("登録したジェスチャー名")) { // 絵が一致した際に処理させたい内容を書く } } } } }
最初にライブラリを読み込み、ジェスチャー後にコールバックされるよう addOnGesturePerformedListener を設定しておきます。
次に読み込む xml layout を見ていきます。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 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="fill_parent" > <!-- ジェスチャー領域に表示させるWidgetを追加 --> </android.gesture.GestureOverlayView> </FrameLayout>
android.gesture.GestureOverlayView がジェスチャー独自Viewとなります。
登録されたジェスチャー情報読込
登録された情報を表示させたい場合は以下のようにします。
String[] entries = mLibrary.getGestureEntries().toArray(new String[0]); Arrays.sort(entries); for (String name : entries) { for (Gesture gesture : mLibrary.getGestures(name)) { gesture.toBitmap(72, 72, 8, 0xFFFFFF00); } }
nameがジェスチャー登録時に設定したName。
Gesture#toBitmapが登録した絵。引数には画像サイズとストローク色を指定できる。
途中nameでソートしてますが、これはジェスチャー登録された順に取得されるので、nameに重み付けをしてソートさせた方が良いからです。
ソートしないと以下の画像みたいな無規則な並びとなります。
ジェスチャーアプリを開発する上での注意点
一致率を高める
ジェスチャーの評価には最小二乗法らしい...と、以前twitterで教えて貰いましたが、これについてはサッパリ分からないで感覚で説明します。
ジェスチャー開始地点とジェスチャー終了地点が重要となります。横線を書くだけのジェスチャーでも、左から右へ書くのと、右から左へ書くのとでは、完成図としては同じでも別物として扱われます。
これが円の場合、左から時計回り、上から時計回り、右から時計回り、下から時計回り、左から反時計回り、上から反時計回り、右から反時計回り、下から反時計回り。。。等の種類があり、一致させるのが困難です。
そこで楽に一致させる方法ですが、以下の事を行うと良いです。
- 始点と終点を明確とする。
- 始点と終点、終点から始点の2種類用意する。
始点と終点を明確とするため、単なる円でも始点と終点を重ねず、少し歯抜けにさせて描く。それを時計回りと反時計回りの2種類用意。
似た絵は描かない
登録されたジェスチャー情報を元に、描かれたジェスチャーに登録されたジェスチャーを付き合わせて一番共通点の多いジェスチャーが候補として選ばれます。
と言うことは、似た図形が多ければ多いほど誤認識が多くなります。
禁止ジェスチャー
縦の一本線は登録できません。