Одна из вещей, которая отличает разработку для мобильных устройств от других платформ, заключается в том, что мобильный телефон или планшет состоит из датчиков и другого оборудования, которое разработчики могут использовать для ввода данных. В этом уроке вы познакомитесь с сенсорной платформой Android. Вы узнаете, как определить, какие датчики доступны на устройстве и как считывать данные с этих датчиков.
Датчики устройства
Следует учитывать три основные категории базовых датчиков: движение, окружающая среда и положение устройства. Датчики движения обнаруживают изменения сил вокруг трех осей устройства: X, Y и Z, как показано здесь:
Датчики движения включают гироскоп, акселерометр и датчики вектора вращения.
Датчики окружающей среды собирают информацию об окружающей среде, в которой находится телефон. Сюда входят датчики влажности и температуры окружающей среды, детектор света и барометры.
Последняя категория базовых датчиков, положение устройства, делает именно то, что вы ожидаете: она определяет положение устройства. В эту категорию входят датчики ориентации и магнитометр.
Любой датчик, который не подпадает под одну из базовых категорий, считается составным датчиком. Эти датчики на самом деле не являются датчиками в традиционном смысле, но вместо этого собирают свои данные от множества других физических датчиков на устройстве и объединяют их. Примеры включают счетчик шагов, датчик силы тяжести и датчик вектора вращения.
Чтение данных датчика
Теперь, когда вы немного узнали о типах датчиков в мобильных устройствах, пришло время начать считывать данные с реального оборудования. Давайте начнем с выяснения того, какие датчики доступны на устройстве.
Обнаружение датчиков на устройстве
Чтобы получить доступ к датчикам на устройстве, вам нужно будет использовать класс SensorManager
, который вы можете получить как системный сервис из Activity
.
1
|
mSensorManager = (SensorManager) getSystemService( Context.SENSOR_SERVICE );
|
Получив SensorManager
, вы можете получить Sensor
по умолчанию на основе типа или получить List
объектов Sensor
на основе параметра типа. В этом примере мы получим List
всех объектов Sensor
, например, так:
1
|
List<Sensor> sensorList = mSensorManager.getSensorList( Sensor.TYPE_ALL );
|
Вы заметите, что мы использовали TYPE_ALL
здесь. Если нам нужно только определенное подмножество датчиков, мы можем передать любой из поддерживаемых атрибутов типа, таких как элементы в следующем, неисключительном списке.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
TYPE_AMBIENT_TEMPERATURE
TYPE_DEVICE_PRIVATE_BASE
TYPE_GAME_ROTATION_VECTOR
TYPE_GEOMAGNETIC_ROTATION_VECTOR
TYPE_GRAVITY
TYPE_GYROSCOPE
TYPE_GYROSCOPE_UNCALIBRATED
TYPE_HEART_BEAT
TYPE_HEART_RATE
TYPE_LIGHT
TYPE_LINEAR_ACCELERATION
TYPE_MAGNETIC_FIELD
TYPE_MAGNETIC_FIELD_UNCALIBRATED
TYPE_MOTION_DETECT
|
Если у вас есть Sensor
с которыми вы хотите работать, вы можете начать извлекать из них данные.
Слушатели событий датчика
Каждый объект Sensor
содержит информацию о физическом оборудовании для этого датчика, например, мощность, задержка на входе, имя, тип и поставщик. Однако, если вы хотите получить информацию от этого датчика, вам нужно зарегистрировать SensorEventListener
который будет вызываться через заданные интервалы с новыми показаниями информации.
1
|
mSensorManager.registerListener( this, mSensor, SensorManager.SENSOR_DELAY_UI );
|
Существует четыре скорости чтения: самая быстрая, игровая, обычная и пользовательский интерфейс. Некоторые позволят вам читать информацию чаще, но будут потреблять больше энергии от устройства. Чем реже опрашивается датчик, тем меньше энергии он будет использовать.
После регистрации onSensorChanged
метод onSensorChanged
слушателя будет вызываться с новым SensorEvent
каждом SensorEvent
датчика. SensorEvent
оборачивает объект Sensor
который предоставляет ему данные, а также информацию о времени, точности датчика и фактических входных данных.
Входные данные хранятся в массиве float
с float
называемых values
. Длина values
может варьироваться в зависимости от датчика. Например, акселерометр будет иметь три значения (вход X, Y и Z), тогда как барометр будет иметь только одно значение. Когда вы используете данные датчика, понимание того, какие данные доступны и как они хранятся в массиве values
будет важно для понимания того, как вы создадите свое приложение, а также избежания сбоев из-за проблем, таких как ArrayIndexOutOfBoundsException
.
1
2
3
4
5
6
7
8
|
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
Log.e(«Tuts+», «Accuracy: » + sensorEvent.accuracy );
Log.e(«Tuts+», «Timestamp: » + sensorEvent.timestamp);
Log.e(«Tuts+», «Accelerometer X: » + sensorEvent.values[0]);
Log.e(«Tuts+», «Accelerometer Y: » + sensorEvent.values[1]);
Log.e(«Tuts+», «Accelerometer Z: » + sensorEvent.values[2]);
}
|
Приведенный выше фрагмент кода при запуске с акселерометром устройства выдаст следующий результат:
1
2
3
4
5
|
E/Tuts+: Accuracy: 3
E/Tuts+: Timestamp: 572565573007319
E/Tuts+: Accelerometer X: 0.80444336
E/Tuts+: Accelerometer Y: 1.7597351
E/Tuts+: Accelerometer Z: 9.425964
|
А поскольку слушатель обеспечивает ввод данных с течением времени, его можно вводить в график для отображения информации, аналогичной следующей (хотя сама библиотека графиков выходит за рамки данного руководства).
Триггеры событий
В то время как SensorEventListener
будет продолжать предоставлять информацию с течением времени, TriggerEventListener
будет прослушивать событие, а затем немедленно отключать себя. Этот тип слушателя используется для таких вещей, как значительное движение. Вы можете добавить TriggerEventListener
в SensorManager
следующим образом.
1
2
3
4
5
6
7
8
9
|
mSensorManager.requestTriggerSensor(new TriggerEventListener() {
@Override
public void onTrigger(TriggerEvent triggerEvent) {
Log.e(«Tuts+», «onTrigger»);
for(int i = 0; i < triggerEvent.values.length; i++ ) {
Log.e(«Tuts+», «item » + i + «: » + triggerEvent.values[i]);
}
}
}, mSensor);
|
Если Sensor
переданный в requestTriggerSensor
является значимым датчиком движения, то вышеприведенное будет иметь выход при перемещении устройства следующим образом:
1
2
|
E/Tuts+: onTrigger
E/Tuts+: item 0: 1.0
|
Одна вещь, которую следует отметить как с SensorEventListener
и с TriggerEventListener
заключается в том, что они должны быть незарегистрированными в вашем SensorManager
когда вы закончите их использовать, например, в onDestroy
в ваших классах Fragment
или Activity
, чтобы предотвратить утечки в вашем приложении.
Вывод
В этом уроке вы познакомились с сенсорной платформой Android. Вы узнали, как находить датчики на устройстве и получать от них информацию. Используя это, вы можете создавать сложные приложения, которые осведомлены об их среде, специальном вводе и действиях пользователей. Умение правильно использовать данные датчиков откроет много интересных функций и возможностей, которые вы можете использовать для своих приложений.