Android学習ノート_140724（端末でのデバッグ、イベント処理 [ キー、タッチ、ジェスチャー ] ）

# 端末でのデバッグ

Androidの実機（Nexus 5）が届いたのでUSBで接続してアプリのインストールをしてみようと思う。

パソコンとAndroid端末の接続をして、Androidの設定から開発者向けオプション、またはアプリケーション→開発という項目がある、と書籍にはあるが、僕の端末にはない。ググると、バージョン4.2以降は、開発者向けオプションを表示させるのに一手間あるようだ。Nexus 5の場合は、設定→端末情報で表示されるビルド番号を7回タップする。

* [Nexus 7 Android 4.2で消えた開発者向けオプションを表示させる方法。 - Android(アンドロイド)おすすめアプリ・カスタムニュース|AndroidLover.Net](http://androidlover.net/smartphone/galaxynexus/android-4-2-developer-options.html)

表示された開発者向けオプションから、USBデバッグをチェックして、端末とPCをUSBで接続してみる。デバイスを微妙に認識していないようだったので、「[Google USB Driver | Android Developers](http://developer.android.com/sdk/win-usb.html)」からドライバをダウンロードする。解凍したフォルダをドライバを手動で指定してインストール。

コマンドプロンプトから`adb devices`で端末情報を表示させようとしたところ、そもそもパスが通ってなかったようでユーザー変数（変数名をANDROID_PATHとしていた）のPATHに追加したら通った。

ソフトウェア・アップデートかけて、Eclipseのプロジェクトファイルからデバックの構成で、逐次デバックの端末を選ぶように設定して、デバッグを実行すると、端末側で表示された。Nexus 5解像度高い。昨日書いたタイリングするコードを表示させてみた。実機でデバッグできるとだいぶモチベーション高まる。

![Screenshot_2014-07-24-01-41-59.png](https://qiita-image-store.s3.amazonaws.com/0/6576/0f37882f-53fe-1c0f-c981-4e3fc25a1925.png)

# イベントの利用

## キーイベント

```java:KeyEx.java
package com.example.keyex;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class KeyEx extends Activity {

	@Override
	protected void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(new KeyExView(this));
	}
}
```

```java:KeyExView.java
package com.example.keyex;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.KeyEvent;
import android.view.View;

public class KeyExView extends View {
	private int keyCode = -999;

	public KeyExView(Context context) {
		super(context);
		setBackgroundColor(Color.rgb(255, 255, 255));
		// フォーカスの指定
		setFocusable(true);
		setFocusableInTouchMode(true);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextSize(24);

		String str = "";
		switch(keyCode){
	        case KeyEvent.KEYCODE_DPAD_UP:
	        	str = "DPAD_UP";
	            break;
	        case KeyEvent.KEYCODE_DPAD_DOWN:
	        	str = "DPAD_DOWN";
	        	break;
	        case KeyEvent.KEYCODE_DPAD_LEFT:
	        	str = "DPAD_LEFT";
	        	break;
	        case KeyEvent.KEYCODE_DPAD_RIGHT:
	        	str = "DPAD_RIGHT";
	        	break;
	        case KeyEvent.KEYCODE_BACK:
	        	str = "DPAD_BACK";
	            break;
	        case KeyEvent.KEYCODE_MENU:
	        	str = "DPAD_MENU";
	        	break;
	        default:
	            System.out.println("Other");
	    }
		canvas.drawText("KeyCode > "+keyCode + " : " + str, 0, 40, paint);
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		this.keyCode = keyCode;
		invalidate();
		return true;
	}
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		this.keyCode = keyCode;
		invalidate();
		return true;
	}
}
```
ボタンを押下すると、対応したキーコードが表示される。正直地味。

## タッチイベント

```java:TouchEx.java
package org.cenkhor.touchex;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class TouchEx extends Activity {

	@Override
	protected void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(new TouchExView(this));
	}
}
```

```java:TouchExView.java
package org.cenkhor.touchex;

import java.util.HashMap;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.View;

public class TouchExView extends View {
	private HashMap<String, PointF> points = new HashMap<String, PointF>();

	public TouchExView(Context context) {
		super(context);
		setBackgroundColor(Color.rgb(255, 255, 255));
		setFocusable(true);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextSize(32);

		canvas.drawText("TouchEx > ", 0, 40, paint);
		// オブジェクト型の配列に、ポイントF（ポイントをX,Yで持つ）のフロート型）のキーを配列で取得
		Object[] keys = points.keySet().toArray();
		for (int i = 0; i < keys.length; i++) {
			// pointsからキーで値（個々のポイント）を取得
			PointF point = (PointF) points.get(keys[i]);
			canvas.drawText("[ " + i + " ] Point X : " + (int) point.x + " Y : "
					+ (int) point.y, 0, 80 + 40 * i, paint);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// アクション種別と、タッチ数を取得
		int action = event.getAction();
		int count = event.getPointerCount();

		// アクションインデックスとポインタIDの取得
		int index = event.getActionIndex();
		int pointerID = event.getPointerId(index);

		// タッチ位置の取得
		switch (action & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_POINTER_DOWN:
			points.put(" " + pointerID, new PointF(event.getX(), event.getY()));
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			points.remove(" " + pointerID);
			break;
		case MotionEvent.ACTION_MOVE:
			for (int i = 0; i < count; i++) {
				PointF point = points.get(" " + event.getPointerId(i));
				point.x = event.getX(i);
				point.y = event.getY(i);
			}
			break;
		}
		// 再描画
		invalidate();
		return true;
	}

}

```

マルチタッチでポイントの座標が取得できる。HashMapを実例で使ったのが初めてだったので結構新鮮だった。

## ジェスチャーイベント

```java:GestureEx.java
package org.cenkhor.gestureex;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class GestureEx extends Activity {

	@Override
	protected void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(new GestureExView(this));
	}
}

```

```java:GestureExView.java
package org.cenkhor.gestureex;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class GestureExView extends View implements
		GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

	private ArrayList<String> info;
	private GestureDetector gestureDetector;

	public GestureExView(Context context) {
		super(context);
		setBackgroundColor(Color.rgb(122, 122, 122));
		setFocusable(true);

		info = new ArrayList<String>();
		info.add("GestureEx : ");
		gestureDetector = new GestureDetector(context, this);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextSize(32);
		for (int i = 0; i < info.size(); i++) {
			canvas.drawText((String) info.get(i), 0, 32 * i + 32, paint);
		}
	}

	private void addInfo(String str) {
		info.add(0, str);
		while (info.size() > (int)(getHeight()/32))
			info.remove(info.size() - 1);
		invalidate();
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		gestureDetector.onTouchEvent(event);
		return true;
	}

	@Override
	public boolean onSingleTapConfirmed(MotionEvent e) {
		addInfo("SingleTap");
		return false;
	}

	@Override
	public boolean onDoubleTap(MotionEvent e) {
		addInfo("DoubleTap");
		return false;
	}

	@Override
	public boolean onDoubleTapEvent(MotionEvent e) {
		addInfo("DoubleTapEvent");
		return false;
	}

	@Override
	public boolean onDown(MotionEvent e) {
		addInfo("Down");
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		addInfo("ShowPress");
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		addInfo("Up");
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		addInfo("Scroll (" + (int) distanceX + " , " + (int) distanceY + ")");
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		addInfo("LongPress");
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		addInfo("Fling (" + (int) velocityX + " , " + (int) velocityY + ")");
		return false;
	}
}
```

GestureExViewクラスは、GestureDetector.OnGestureListenerとGestureDetector.OnDoubleTapListenerインターフェイスを実装してる（からメソッドがたくさんある）。こういうのIDEなかったら死ぬ気がする。ArrayListにデータをどんどん詰めていってDrawTextで表示させつつ、画面から溢れたら、リストの長さ以上のものはリムーブするというのは実装手法として使いそうだなーと思った。size,get,removeなどメソッド名にはなかなか慣れなくて、毎回補完のリスト眺めてる。

サーフェイスビューの利用まで進めたけど、きりがいいのでここまで。

# Android Nexus 5 Wi-Fiのセットアップ

家のWi-Fiに接続しようとしたら、繋がらない。無線LAN親機側で、チャンネルの設定が必要みたいだ。これは出かける時間になってしまったので、帰宅して検証する。出先でテザリングしてソフトウェアアップデートかけた。

* [Nexus 7 Android 4.2で消えた開発者向けオプションを表示させる方法。 - Android(アンドロイド)おすすめアプリ・カスタムニュース|AndroidLover.Net](http://androidlover.net/smartphone/galaxynexus/android-4-2-developer-options.html)