Help us understand the problem. What is going on with this article?

Android端末に搭載されているセンサーの一覧を取得する(その2)

More than 3 years have passed since last update.

Android端末に搭載されているセンサーの一覧を取得するの続きです。

前回、以下のように書きました。

Sensor.TYPE_XXっていうのが、Sensorのページを見るとConstantsの一覧に書いてあって、「Class representing a sensor. Use getSensorList(int) to get the list of available Sensors.」とされているので、まあ、やりたいことのほとんどはこの辺りのドキュメントに書いてある感じですね。

ということで、前回書いたコードを、getSensorList(int)を使って書き直そうと思います。

getSensorList()でセンサー一覧を取得する

getSensorList() は、引数として Sensor.TYPE_ALL を指定すると、List形式でSensorを返します。そこを修正します。

以下のように、自作のSensorItem型のインスタンスのArrayListを作成するinitSensorList()というメソッドを作っていました。

private ArrayList<SensorItem> sensorList;
private void initSensorList(){
    sensorList = new ArrayList<SensorItem>();
    sensorList.add( new SensorItem(Sensor.TYPE_ACCELEROMETER, "ACCELEROMETER"));
    sensorList.add( new SensorItem(Sensor.TYPE_AMBIENT_TEMPERATURE,"AMBIENT_TEMPERATURE"));
    sensorList.add( new SensorItem(Sensor.TYPE_DEVICE_PRIVATE_BASE,"DEVICE_PRIVATE_BASE"));
    sensorList.add( new SensorItem(Sensor.TYPE_GAME_ROTATION_VECTOR,"GAME_ROTATION_VECTOR"));
    sensorList.add( new SensorItem(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR,"GEOMAGNETIC_ROTATION_VECTOR"));
    sensorList.add( new SensorItem(Sensor.TYPE_GRAVITY, "GRAVITY"));
    sensorList.add( new SensorItem(Sensor.TYPE_GYROSCOPE, "GYROSCOPE"));
    sensorList.add( new SensorItem(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, "GYROSCOPE_UNCALIBRATED"));
    sensorList.add( new SensorItem(Sensor.TYPE_HEART_BEAT, "HEART_BEAT"));
    sensorList.add( new SensorItem(Sensor.TYPE_HEART_RATE, "HEART_RATE"));
    sensorList.add( new SensorItem(Sensor.TYPE_LIGHT, "LIGHT"));
    sensorList.add( new SensorItem(Sensor.TYPE_LINEAR_ACCELERATION, "LINEAR_ACCELERATION"));
    sensorList.add( new SensorItem(Sensor.TYPE_MAGNETIC_FIELD, "MAGNETIC_FIELD"));
    sensorList.add( new SensorItem(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, "MAGNETIC_FIELD_UNCALIBRATED"));
    sensorList.add( new SensorItem(Sensor.TYPE_MOTION_DETECT, "MOTION_DETECT"));
    sensorList.add( new SensorItem(Sensor.TYPE_POSE_6DOF, "POSE_6DOF"));
    sensorList.add( new SensorItem(Sensor.TYPE_PRESSURE, "PRESSURE"));
    sensorList.add( new SensorItem(Sensor.TYPE_PROXIMITY, "PROXIMITY"));
    sensorList.add( new SensorItem(Sensor.TYPE_RELATIVE_HUMIDITY, "RELATIVE_HUMIDITY"));
    sensorList.add( new SensorItem(Sensor.TYPE_ROTATION_VECTOR, "ROTATION_VECTOR"));
    sensorList.add( new SensorItem(Sensor.TYPE_SIGNIFICANT_MOTION, "SIGNIFICANT_MOTION"));
    sensorList.add( new SensorItem(Sensor.TYPE_STEP_COUNTER, "STEP_COUNTER"));
    sensorList.add( new SensorItem(Sensor.TYPE_STEP_DETECTOR, "STEP_DETECTOR"));
}

これを、廃して、onCreate()の中で、一行で済ませます。

private SensorManager sensorManager;
private List<Sensor> sensorList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sensor_list);

    sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
    sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);

    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
    setListAdapter(adapter);
    listSensors();
}

Sensorのリストを作成しListViewに追加する

listSensors() methodにて、adapterに取得したSensorを追加します。

private void listSensors(){
    for (int i=0; i<sensorList.size(); i++){
        Sensor s = sensorList.get(i);
        StringBuilder sb = new StringBuilder();
        sb.append(s.getStringType()).append(": ").append(s.getName());
        adapter.add(sb.toString());
        sensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
    }
}

for文の最後で、取得したSensorをregisterListener()して、Sensorからの値を取得できるように準備します。

ListViewにClickedイベントを追加

前回、以下のように書いていたのですが、ToastでSensorの情報を表示するようにしていました。

ListActivityに表示されるlistItemはそれぞれclickableなので、これをクリックしたら、取得したsensorの値を表示するようにするのは、そんなに大変な拡張ではないはずなので、次はその辺りを目指してみようと思います。

ここを、変更して、ListViewで選んだSensorの情報を表示するフィールドを画面下部に作成し、そこに情報を表示するように大きくlayoutファイルを変更します。

その上で、onListItemClick()methodを書き換えます。

private int sensortype = -1;
private TextView sensorType;
private TextView sensorName;
private TextView sensorValue;

@Override
protected void onCreate(Bundle savedInstanceState){
    // ... (略) ... 
    sensorType = (TextView)findViewById(R.id.sensor_type);
    sensorName = (TextView)findViewById(R.id.sensor_name);
    sensorValue = (TextView)findViewById(R.id.sensor_value);
    // ... (略) ... 
}

@Override
protected void onListItemClick(ListView lv, View v, int position, long id){
    Sensor s = sensorList.get(position);
    sensortype = s.getType();
    sensorType.setText(s.getStringType());
    sensorName.setText(s.getName());
    sensorValue.setText(s.toString());
}

sensorType, sensorName, sensorValueを備えたLayoutを、以下のように作成します。

<LinearLayout android:weightSum="5">![Screenshot_1496829244.png](https://qiita-image-store.s3.amazonaws.com/0/15553/e5ad5b78-4164-ac36-370c-14118cc82f9b.png "Screenshot_1496829244.png")

    <LinearLayout android:layout_weight="3">
        <ListView android:id="@android:id/list" />
    </LinearLayout>
    <LinearLayout android:layout_weight="2">
        <TextView android:id="@+id/sensor_type" />
        <TextView android:id="@+id/sensor_name" />
        <TextView android:id="@+id/sensor_value" />
    </LinearLayout>
</LinearLayout>

動作イメージ

Screenshot_1496829244.png

こなれてませんが、こんな感じになります。

まとめ

以上により、以下のことが可能になりました。

  • Sensorの一覧を取得
  • Sensorの一覧をクリックしたら、画面下部のフィールドにSensor情報を表示

本日のコード

package jp.gr.java_conf.fukuit.sensoractivity;
/**
 * SensorListActivity
 *   Set ListView to SensorName and Status
 */

import java.util.List;
import android.app.ListActivity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
import android.hardware.SensorEventListener;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class SensorListActivity extends ListActivity implements SensorEventListener{
    private SensorManager sensorManager;
    private List<Sensor> sensorList;
    private ArrayAdapter<String> adapter;

    private int sensortype;

    private TextView sensorType;
    private TextView sensorName;
    private TextView sensorValue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sensor_list);

        sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);

        sensorType = (TextView)findViewById(R.id.sensor_type);
        sensorName = (TextView)findViewById(R.id.sensor_name);
        sensorValue = (TextView)findViewById(R.id.sensor_value);

        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
        setListAdapter(adapter);

        listSensors();
    }

    @Override
    protected void onResume() {
        super.onResume();
        listSensors();
    }

    @Override
    protected void onListItemClick(ListView lv, View v, int position, long id) {
        Sensor s = sensorList.get(position);
        sensortype = s.getType();

        sensorType.setText(s.getStringType());
        sensorName.setText(s.getName());
        sensorValue.setText(s.toString());
    }

    private void listSensors(){
        for(int i=0; i < sensorList.size(); i++) {
            Sensor s = sensorList.get(i);
            StringBuilder sb = new StringBuilder();
            sb.append(s.getStringType()).append(": ").append(s.getName());
            adapter.add(sb.toString());
            sensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event){
        if (sensortype != -1){
            if (event.sensor.getType() == sensortype){
                String value = String.valueOf(event.values[0]);
                sensorValue.setText(value);
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy){
    }
}
fukuit
最近、事務系の職場に異動したので、職業プログラマではなくなりました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away