2010年2月22日月曜日

[Android] 가속도센서를 사용해보다.

Android 가속센서를 사용해보다.

가속도센서를 등록하면 SensorEvent의 values배열에 x, y, z의 가속도가 순서대로 들어오기 때문에 의외로 간단하게 사용할 수 있었다.

가속도센서에 따라 이미지가 움직인다.



Activity를 등록할 때 화면을 수직으로 고정시켰다.(수직방향이 계산하기 쉬워서)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.babukuma.android.test" android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".SensorActivity" android:screenOrientation="portrait"
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>
<uses-sdk android:minSdkVersion="4" />
</manifest>


확인하기 편하도록 화면에는 간단한 이미지를 출력하고 가속도에 따라 위치를 변경시키도록 하였다.

package com.babukuma.android.test;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class SensorActivity extends Activity implements SensorEventListener {
private static final String LOG_TAG = "BABUKUMA";

private SensorManager sensorManager;
private SensorView sensorView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensorView = new SensorView(this);
setContentView(sensorView);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

// 加速度センサー
List<Sensor> sensors = sensorManager
.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (sensors.size() > 0) {
sensorManager.registerListener(this, sensors.get(0),
SensorManager.SENSOR_DELAY_GAME);
}
}

@Override
protected void onDestroy() {
super.onDestroy();
sensorManager.unregisterListener(this);
}

@Override
public void onAccuracyChanged(final Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}

@Override
public void onSensorChanged(final SensorEvent event) {
Sensor sensor = event.sensor;
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
// Log.d(LOG_TAG, "ACCELEROMETER : " + event.values[0] + ","
// + event.values[1] + "," + event.values[2]);
sensorView.move(event.values[0], event.values[1]);

break;
default:
break;
}
}

class SensorView extends View {
private static final int KUMA_SIZE = 50;
private Bitmap kuma;
private int w;
private int h;
private float x;
private float y;

public SensorView(Context context) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
kuma = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_kuma_50);
}

/**
* クマを移動する。
*
* @param mx
* @param my
*/
public void move(float mx, float my) {
this.x -= (mx * 4f);
this.y += (my * 4f);

if (this.x < 0) {
this.x = 0;
} else if ((this.x + KUMA_SIZE) > this.w) {
this.x = this.w - KUMA_SIZE;
}

if (this.y < 0) {
this.y = 0;
} else if ((this.y + KUMA_SIZE) > this.h) {
this.y = this.h - KUMA_SIZE;
}

invalidate();
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
this.w = w;
this.h = h;
this.x = (w - KUMA_SIZE) / 2f;
this.y = (h - KUMA_SIZE) / 2f;
}

@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(kuma, x, y, null);
}
}
}