Pull to refresh

Собираем показания датчиков с Android смартфона

Reading time4 min
Views67K
В своем первом посте на Хабре я бы хотел рассказать о том, как получать данные датчиков в ОС Android, а конкретно — угол наклона вашего аппарата во всех трех плоскостях. Заинтересовавшихся прошу под кат.


Датчики ОС Android делятся на три категории: движения, положения и окружающей среды. Датчики эти могут быть самыми разными:
  • Акселерометр
  • Гироскоп
  • Датчик освещения
  • Датчик магнитных полей
  • Акселерометр
  • Барометр
  • Датчик поднесения телефона к голове
  • Датчик температуры аппарата
  • Датчик температуры окр. среды
  • Измеритель относительной влажности
  • И т.д.


Естественно, их набор зависит от «комплектации» аппарата, но есть и датчики, присутствующие в большинстве смартфонов на Android — акселерометр и гироскоп.

Посредством этих датчиков мы можем узнать положение телефона в пространстве, а именно углы наклона аппарата во всех трех плоскостях (XY, YZ, ZX). Этим мы и займемся!

Для начала создадим новый проект и накидаем простенькое отображение с тремя надписями для вывода показаний датчиков и соответствующими подписями к ним. У меня получилось что-то вроде этого:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="25dp"
            android:text="Угол XY" />

        <TextView
            android:id="@+id/xyValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="25dp"
            android:text="0" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView3"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="25dp"
            android:text="Угол XZ" /> />

        <TextView
            android:id="@+id/xzValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="25dp"
            android:text="0" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView5"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="25dp"
            android:text="Угол ZY" />

        <TextView
            android:id="@+id/zyValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="25dp"
            android:text="0" />

    </LinearLayout>

</LinearLayout>


В главной активити объявление класса приведем к виду:

public class Main extends Activity implements SensorEventListener {


Класс SensorEventListener поможет нам отследить события на датчиках.

У вас должно появиться четыре обязательных метода:

@Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) { //Изменение точности показаний датчика
  }

@Override
  protected void onResume() {
  }

@Override
  protected void onPause() {
  }

@Override
  public void onSensorChanged(SensorEvent event) { //Изменение показаний датчиков
  }


Как вы уже наверное догадались, нас вскоре заинтересует последний метод. А пока объявим необходимые нам переменные:

  private SensorManager mSensorManager; 
  private Sensor mOrientation;

  private float xy_angle;
  private float xz_angle;
  private float zy_angle;

  private TextView xyView;
  private TextView xzView;
  private TextView zyView;


Первая переменная — менеджер сенсоров устройства. Именно она даст нам доступ к интересующему нас датчику. Для этого событие onCreate сделаем похожим на это:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // Получаем менеджер сенсоров
    mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); // Получаем датчик положения
    
    xyView = (TextView) findViewById(R.id.xyValue);  //
    xzView = (TextView) findViewById(R.id.xzValue);  // Наши текстовые поля для вывода показаний
    zyView = (TextView) findViewById(R.id.zyValue);  //
  }


Ну вот, почти закончили! Осталось только получить значения и вывести в текстовые поля. Вспомним про событие onSensorChanged. Если помните в него передается параметр SensorEvent event. Он-то и содержит значения углов наклона в градусах. Поэтому делаем финальный штрих и приводим событие к виду:

public void onSensorChanged(SensorEvent event) {
    xy_angle = event.values[0]; //Плоскость XY
    xz_angle = event.values[1]; //Плоскость XZ
    zy_angle = event.values[2]; //Плоскость ZY
    
    xyView.setText(String.valueOf(xy_angle));
    xzView.setText(String.valueOf(xz_angle));
    zyView.setText(String.valueOf(zy_angle));
}


Все готово! Думаю, понятно, что виртуальный смартфон вы повертеть не сможете. Поэтому для тестирования вам понадобится реальный аппарат. Запускаем, вертим наш смартфон и следим за цифрами.

Если кому-то понадобится, то выкладываю apk сделаный по примеру.

Надеюсь, пост оказался полезным и понятным для вас!

UPD: Как оказалось, можно протестировать и в эмуляторе. Спасибо BlackStream за ссылку!
Tags:
Hubs:
Total votes 26: ↑20 and ↓6+14
Comments18

Articles