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>
動作イメージ
こなれてませんが、こんな感じになります。
まとめ
以上により、以下のことが可能になりました。
- 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){
}
}