Android開発 - 方位センサー

2011/07/10 23:15Update
TAGS: Android | 開発 | 方位センサー | Sensor | SensorManager

Androidの方位センサーの利用方法について。

はじめに


Android開発入門 Hello world
Android開発 ドラッグ&ドロップでアプリにウィジェット追加
Android開発 - 副画面を作成


センサーの利用方法(手順)について


■センサー関連のクラス
android.hardware.Sensor;
android.hardware.SensorEvent;
android.hardware.SensorEventListener;
android.hardware.SensorManager;

■センサー利用の手順として
1)SensorManagerインスタンスを取得
SensorManager sensorManager =  (SensorManager) getSystemService(SENSOR_SERVICE);


2)センサーを取得
例えば、加速度センサーの取得の場合
//加速度センサーリスト
List<Sensor> accelerometerSensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);


3)センサーのイベント・リスナー登録
Sensor accelerometerSensor = accelerometerSensorList.get(0);
sensorManager.registerListener(sensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_FASTEST);


4)SensorEventListener.onSensorChanged(SensorEvent event)を実装


Androidが提供しているセンサーの種類について

Sensor.TYPE_ALL    全部のセンサー
Sensor.TYPE_ACCELEROMETER    加速度センサー
Sensor.TYPE_GYROSCOPE    ジャイロスコープセンサー
Sensor.TYPE_LIGHT    照度(環境光)センサー
Sensor.TYPE_MAGNETIC_FIELD    地磁気センサー
Sensor.TYPE_ORIENTATION    方位(非推奨)センサー
Sensor.TYPE_PRESSURE    加圧センサー
Sensor.TYPE_PROXIMITY    接近センサー
Sensor.TYPE_TEMPERATURE    温度センサー

TYPE_ORIENTATIONが非推奨で、方位センサーを利用するのに、
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
を使わず、かえって加速度センサーと磁気センサーから得た値を
SensorManager.getRotationMatrixやSensorManager.remapCoordinateSystemなどのメソッドで変換をかけ、最終的に方位値を取得します。

float[] inR = new float[16];
SensorManager.getRotationMatrix(inR, null, 加速度センサー値, 地磁気センサー値);

float[] outR = new float[16];
SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);

float[] ori = SensorManager.getOrientation(outR, new float[3]);

float x = ori[0];    //X軸
float y = ori[1];    //Y軸
float z = ori[2];    //Z軸



以下は方位センサーの利用方法の例です。

レイアウト定義



sensor.xml
<?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">
    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/linearLayout1">
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="センサー名:" android:id="@+id/textView1"></TextView>
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:id="@+id/sensorName"></TextView>
    </LinearLayout>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="センサー値を取得:" android:id="@+id/textView3"></TextView>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:id="@+id/sensorValue"></TextView>
    
</LinearLayout>


Activityクラス


OrientationSensorActivity.java
package com.syboos.android;

import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class OrientationSensorActivity extends Activity implements
        SensorEventListener {
    //センサー・マネージャ
    private SensorManager sensorManager;
    
    private Sensor accelerometerSensor;    //加速度センサー
    private Sensor magneticFieldSensor;    //磁気センサー
    
    //センサー表示関連のTextView
    private TextView sensorName;    //センサー名
    private TextView sensorValue;    //センサー値
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sensor);
        
        //センサー表示
        sensorName = (TextView)findViewById(R.id.sensorName);
        sensorValue = (TextView)findViewById(R.id.sensorValue);
                
        sensorName.setText("方位センサー");
        
        ////////////////////////////////////////
        //SensorManagerインスタンスを取得
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        
        //加速度センサーリスト
        List<Sensor> accelerometerSensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
        //磁気センサーリスト
        List<Sensor> magneticFieldSensorList = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
        if (!accelerometerSensorList.isEmpty() && !magneticFieldSensorList.isEmpty()) {
            accelerometerSensor = accelerometerSensorList.get(0);
            //accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            
            magneticFieldSensor = magneticFieldSensorList.get(0);
            //magneticFieldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        }
    }
    /* 
     * センサーの精度が変更された時に呼び出される
     */
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //今回は利用しない
    }

    @Override
    protected void onResume() {
        super.onResume();
        
        if (accelerometerSensor != null && magneticFieldSensor != null) {
            //リスナーの登録
            sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_FASTEST);
            sensorManager.registerListener(this, magneticFieldSensor, SensorManager.SENSOR_DELAY_FASTEST);
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        if (accelerometerSensor != null && magneticFieldSensor != null) {
            //リスナーの解除
            sensorManager.unregisterListener(this, accelerometerSensor);
            sensorManager.unregisterListener(this, magneticFieldSensor);
        }
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        
        sensorManager.unregisterListener(this);
    }
    public void onSensorChanged(SensorEvent event) {
        float [] aValues = null;
        float [] mValues = null;
        
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            aValues = event.values.clone();
        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            mValues = event.values.clone();
        }
        
        if (aValues != null && mValues != null) {
            float[] inR = new float[16];

            if (SensorManager.getRotationMatrix(inR, null, aValues, mValues)) {
                float[] outR = new float[16];
                SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
                float[] ori = SensorManager.getOrientation(outR, new float[3]);
            
                float x = ori[0];    //X軸
                float y = ori[1];    //Y軸
                float z = ori[2];    //Z軸
                
                this.sensorValue.setText(
                        "[X軸=" + x + "] " +    
                        "[Y軸=" + y + "] " +
                        "[Z軸=" + z + "] ");
            }
        }
    }

}

.

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation