[Android] 加速度センサー( SensorEventListener, SensorSimulator )

実機がないので未検証だけど加速度センサーを使う方法のメモ

SensorEventListenerを実装するコード

SensorEventListenerインターフェイスで実装すべきメソッドは

public abstract void onAccuracyChanged (Sensor sensor, int accuracy)

public abstract void onSensorChanged (SensorEvent event)

でも onAccuracyChanged はなにやら問題あり?

これの中身は基本的には何も書かない。

package jp.fernweh;

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.LinearLayout;
import android.widget.TextView;

public class AccelerometerTestActivity
  extends Activity implements SensorEventListener {

  SensorManager mSensorManager;
  TextView mX, mY, mZ;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Activity#getSystemService(String name)
    // でSensorManagerインスタンスを取得
    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    setContentView(layout);

    mX = new TextView(this);
    mX.setText("残念ながら");
    layout.addView(mX);

    mY = new TextView(this);
    mY.setText("エミュレータでは");
    layout.addView(mY);

    mZ = new TextView(this);
    mZ.setText("動きません!");
    layout.addView(mZ);
  }

  @Override
  protected void onResume() {
    super.onResume();
    // SensorManager#getSensorList(int type)
    // Sensor.TYPE_ACCELEROMETER は加速度センサー
    // 他には Sensor.TYPE_TEMPERATURE(温度センサー) など
    // 返り値は List<Sensor> - Sensorインスタンスのリスト
    List<Sensor> sensors = mSensorManager
        .getSensorList(Sensor.TYPE_ACCELEROMETER);

    // SensorManager#registerListenerでリスナーを登録
    for (Sensor sensor : sensors) {
      mSensorManager.registerListener(this, sensor,
          // SensorManager.SENSOR_DELAY_NORMAL
          // SensorManager.SENSOR_DELAY_FASTEST
          // データ取得の間隔
          SensorManager.SENSOR_DELAY_NORMAL);
    }
  }

  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // センサーの精度変更時にコールされるらしい。
    // 引数は変更されたセンサーと精度らしいけど
    // 具体的にどう使うのかいまいち分からない

    // 基本的には何も書かなくても問題ないらしい
  }

  @Override
  public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
      // この中で変数を宣言すると
      // 起動中は破棄されないため
      // メモリリークするので注意

      // できるだけ軽く済ませよう…
      mX.setText(String.valueOf(event.values[SensorManager.DATA_X]));
      mY.setText(String.valueOf(event.values[SensorManager.DATA_Y]));
      mZ.setText(String.valueOf(event.values[SensorManager.DATA_Z]));
    }
  }

  @Override
  protected void onStop() {
    super.onStop();
    // リスナーの登録解除
    mSensorManager.unregisterListener(this);
  }
}

実機を持っていないのでこれで動くかどうかは不明。一応エミュレータでエラー無しに起動はできる。

SensorSimulatorで実行するためのコード

実機がない場合はSensorSimulatorである程度代用できる。

SensorSimulator(導入編): Androidアプリ開発

SensorSimulator(コーディング編): Androidアプリ開発

を参考に設定すればOK。ただソースコードは古いため "SensorSimulator - openintents - Sensor Simulator for simulating sensor data in real time. - Make Android applications work together. - Google Project Hosting"(ttp://code.google.com/p/openintents/wiki/SensorSimulator) リンク切れ - githubにSensorSimulator移動した? を参考にコードを書き変える。

とりあえず書き変えたコード

package jp.fernweh;

// SensorSimulatorを使うためのクラスをインポート
import org.openintents.sensorsimulator.hardware.Sensor;
import org.openintents.sensorsimulator.hardware.SensorEvent;
import org.openintents.sensorsimulator.hardware.SensorEventListener;
import org.openintents.sensorsimulator.hardware.SensorManagerSimulator;

import android.app.Activity;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;

public class SensorSimulatorTestActivity
  extends Activity implements SensorEventListener {

  // SensorManagerSimulator型に変更
  SensorManagerSimulator mSensorManager;
  TextView mX, mY, mZ;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /*  mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); */
    // SensorManagerSimulatorインスタンスの取得
    mSensorManager = SensorManagerSimulator.getSystemService(this,
        SENSOR_SERVICE);
    mSensorManager.connectSimulator();

    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    setContentView(layout);

    mX = new TextView(this);
    layout.addView(mX);

    mY = new TextView(this);
    layout.addView(mY);

    mZ = new TextView(this);
    layout.addView(mZ);
  }

  @Override
  protected void onResume() {
    super.onResume();
    // リスナーを登録
    mSensorManager.registerListener(this,
        mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
        SensorManager.SENSOR_DELAY_NORMAL);

  }

  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
  }

  @Override
  public void onSensorChanged(SensorEvent event) {
    // event.sensor.getType() を event.type に変更
    if ( event.type == Sensor.TYPE_ACCELEROMETER) {
      mX.setText(String.valueOf(event.values[SensorManager.DATA_X]));
      mY.setText(String.valueOf(event.values[SensorManager.DATA_Y]));
      mZ.setText(String.valueOf(event.values[SensorManager.DATA_Z]));
    }
  }

  @Override
  protected void onStop() {
    super.onStop();
    mSensorManager.unregisterListener(this);
  }
}

SensorSimulator がちゃんとセッティングできていれば動くはず。

メモ - エミュレータにセンサーシュミレータをインスコ

SensorSimulatorSettings-1.1.0-rc1.apkを /android-sdk-windows/platform-tools/ にコピーしてから、コマンドプロンプトでこんな感じにインストール

D:\>cd android-sdk-windows\platform-tools

D:\android-sdk-windows\platform-tools>adb install SensorSimulatorSettings-1.1.0-rc1.apk
139 KB/s (60553 bytes in 0.423s)
        pkg: /data/local/tmp/SensorSimulatorSettings-1.1.0-rc1.apk
Success
Share
関連記事