Работа с датчиком ускорений в Android

Работа с датчико ускорения в androidЗамечательной особенностью современных смартфонов является их богатое оснащение вспомогательными системами: камера, GPS приемник, встроенные датчики поворота, акселерометры. Все это богатство существенно расширяет горизонты функционального применения телефона. В Этой статье я расскажу об использовании сенсоров, а точнее датчика ускорения, в Android. Мы разработаем простую программу, которая меняет цвет заднего фона, когда Вы трясете телефон.

Работа со встроенными датчиками в Android осуществляется через класс SensorManager. Получить доступ к экземпляру этого класса можно через метод getSystemService(SENSOR_SERVICE). Внутри класса Sensor определено несколько констант, определяющих тип используемого сенсора:

  •     Sensor.TYPE_GYROSCOPE - гироскоп (датчик поворота)
  •     Sensor.TYPE_MAGNETIC_FIELD - магнитное поле
  •     Sensor.TYPE_ORIENTATION - ориентация
  •     Sensor.TYPE_ACCELEROMETER - акселерометр

Для доступа к сенсору используется метод sensorManager.getDefaultSensor(), который в качестве параметров принимает указанный выше тип датчика и константу, определяющую частоту опроса датчика:

  • SENSOR_DELAY_FASTEST - получать данные так часто, насколько это вообще возможно;
  • SENSOR_DELAY_GAME - режим, пригодный для использования в играх.
  • SENSOR_DELAY_NORMAL - этот режим используется по умолчанию. Частота опроса датчиков позволяет использовать их для фиксации факта поворота телефона.
  • SENSOR_DELAY_UI - этот режим предназначен для решения задач пользовательского интерфейса.

Указанные режимы приведены в порядке уменьшения частоты опроса датчиков.

После того, как Вы получили объект, представляющий сенсор, Вы должны зарегистрировать для него класс, реализующий интерфейс SensorEventListener, то есть содержащий метод обработки событий, генерируемых сенсорами.
public void onSensorChanged(SensorEvent event)
 
Работа с сенсорами не представляет ничего сложного. Давайте для  напишем приложение, которое будет менять цвет фона при тряске. Создайте новое приложение и назовите главную деятельность SensorTestActivity.

Приведите шаблон дизайна res/layout/main.xml к виду

<?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" >
 
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Shake to get a toast and to switch color" />
 
</LinearLayout>

Как видите, мы добавили TextView и растянули его на весь экран.

Перейдем к редактированию файла с исходным кодом src\SensorTestActivity.java. Добавим в класс приватное поле sensorManager, которе будет отвечать за работу с датчиком, логическое поле color, которое будет индикатором текущего цвета фона, поле view для работы с TextView и переменную lastUpdate, которая будет хранить время последнего изменения состояния датчика.

private SensorManager sensorManager;//Объект для работы с датчиком
private boolean color=false;//Индикатор текущего цвета: false-зеленый, true - красный.
private View view;//Ссылка на TextView
private long lastUpdate;//Время последнего изменения состояния датчика

Внутри конструктора класса создадим объект sensorManager, предназначенный для работы с датчиками. После этого зарегистрируем класс, внутри которого будут реализованы методы, вызываемые при изменении состояния датчика. Делаеся это с помощью метода sensorManager.registerListener. В качестве первого параметра укажем ссылку на текущий класс (то есть на SensorTestActivity), второй параметр определяет интересующий нас датчик, третий - режим работы датчика.  После регистрации класса инициализируем переменную lastUpdate, записав туда текущее время.

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
 
view= findViewById(R.id.textView);
view.setBackgroundColor(Color.GREEN);
//Создаем объект, для работы с датчиками
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
//Регистрируем класс, где будет реализован метод, вызываевый при изменении
//состояния датчика.
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
lastUpdate=System.currentTimeMillis();
}

Определим также методы  onPause() и onResume(), внутри которых будем регистрировать и снимать регистрацию обработчика событий от датчиков. Это позволит не тратить заряд батареи на работу датчиков, когда приложение находится в спящем режиме.

@Override
protected void onResume(){
super.onResume();
// register this class as a listener for the orientation and
// accelerometer sensors
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
 
@Override
protected void onPause(){
// unregister listener
super.onPause();
sensorManager.unregisterListener(this);
}

Нам осталось реализовать метод onSensorChanged(SensorEvent event), который обрабатывает изменения состояния датчиков. Во первых, мы будем обрабатывать только события от аксилерометра. Значения проекции ускорения на оси системы координат, связанной с телефоном можно получить из массива event.values. В переменную accelationSquareRoot записываем квадрат модуля ускорения телефона, деленный на квадрат ускорения свободного падения. Чем больше значение этой переменной, тем сильнее пользователь трясет телефон. Чтобы избежать случайных срабатываний, будем менять фон TextView только если пользователь трясет телефон дольше, чем 200 миллисекунд.

public void onSensorChanged(SensorEvent event){
if(event.sensor.getType()== Sensor.TYPE_ACCELEROMETER){
float[] values= event.values;
// проекции ускорения на оси системы координат
float x= values[0];
float y= values[1];
float z= values[2];
 
// квадрат модуля ускорения телефона, деленный на квадрат
//ускорения свободного падения
float accelationSquareRoot=(x* x+ y* y+ z* z)
/(SensorManager.GRAVITY_EARTH* SensorManager.GRAVITY_EARTH);
//Текущее время
long actualTime=System.currentTimeMillis();
 
if(accelationSquareRoot>=2)//Если тряска сильная
{
if(actualTime- lastUpdate<200){
//Если с момента начала тряски прошло меньше 200
// миллисекунд - выходим из обработчика
return;
}
lastUpdate= actualTime;
//Меняем цвет
if(color){
view.setBackgroundColor(Color.GREEN);
}else{
view.setBackgroundColor(Color.RED);
}
color=!color;
}
}
 
}

Некоторого пояснения требует на мой взгляд значения, содержащиеся в массиве event.values. Система координат, связанная с телефоном показана на рисунке. Если вы положите телефон на стол и начнете двигать его ускорено вправо, то значение event.values[0] (проекция ускорения на ось x) будет положительным; если влево - отрицательным. Даже если телефон лежит неподвижно на столе, датчик ускорения фиксирует воздействие гравитационной силы и event.values[2]=9.81.


Система координат

   
Вот собственно и все. Как видите, работа с акселерометром является довольно простым делом. Исходник класса можно скачать тут:SensorTestActivity.java.

Александр Ледков
Источники: developer.android.com




Наши соцсети

Подписаться Facebook Подписаться Вконтакте Подписаться Twitter Подписаться Google Подписаться Telegram

Популярное

Ссылки

Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3]) Android / Архив

Рейтинг@Mail.ru Яндекс.Метрика
MobiLab.ru © 2005-2018
При использовании материалов сайта ссылка на www.mobilab.ru обязательна