Sensor APIs
Sensor APIs - это набор интерфейсов, построенных по общему дизайну, которые последовательно предоставляют доступ к датчикам устройств на веб-платформе.
Концепции и использование Sensor APIs
Несмотря на то, что спецификация Generic Sensor API определяет интерфейс Sensor
, вам, как веб-разработчику, не придётся его использовать. Вместо него, для получения данных с конкретных датчиков, вы будете использовать один из его подклассов. Например, интерфейс Accelerometer
возвращает ускорение перемещения устройства по всем трём осям на момент его считывания.
Данные с датчиков могут точно соответствовать данным с физических датчиков устройства, либо не соответствовать им. Например, интерфейс датчика Gyroscope
точно соответствует интерфейсу физического датчика. В качестве альтернативы, интерфейс AbsoluteOrientationSensor
предоставляет информацию, которая алгоритмически объединяет данные с двух и более датчиков устройста. Два эти типа датчиков называются низкоуровневыми и высокоуровневыми соответственно. Второй тип так же называют объединяющим датчиком (либо, виртуальным или, синтетическим).
Возможность использования
Интерфейсы датчиков - это только прокси для датчиков устройства. Как следствие, задача определения возможности использования датчиков гораздо сложнее, чем для других API. Наличие API датчика не значит, что этот API подключен к реальному аппаратному датчику, работает ли он, подключен или, даже, предоставил ли пользователь к нему доступ. Обеспечение постоянного доступа ко всей этой информации приводит к снижению производительности и разряду батареи.
Таким образом, определение возможности использования API датчиков должно включать определение наличия самого этого API и стратегии оборонительного программирования (см. ниже).
Пример ниже показывает три метода определения API датчика. Кроме того, вы можете обернуть создание экземпляра объекта в блок try...catch
. Обратите внимание, что определение через интерфейс Navigator
не единственный возможный путь.
if (typeof Gyroscope === "function") {
// бег по кругу...
}
if ("ProximitySensor" in window) {
// берегись!
}
if (window.AmbientLightSensor) {
// погрузись во тьму...
}
Оборонительное программирование
Как указано в разделе Возможность использования, проверить наличие конкретного API датчика недостаточно. Наличие фактического датчика также должно быть подтверждено. Как раз здесь и необходимо оборонительное программирование. Оно включает три стратегии.
- Проверка на наличие ошибок при создании экземпляра объекта датчика.
- Прослушивание ошибок, возникающих во время его использования.
- Корректная обработка ошибок для улучшения, а не ухудшения пользовательского опыта.
Приведенный ниже пример кода иллюстрирует эти принципы. Блок try...catch
ловит ошибки, возникающие при создании объекта датчика. Этот объект слушает события error
, чтобы поймать ошибки, возникающие во время использования датчика. Единственный раз, когда что-либо показывается пользователю, это когда необходимо запросить разрешения и когда датчик не поддерживается устройством.
Примечание: Если функциональная политика блокирует использование функции, то это происходит потому, что ваш код не соответствует политикам, установленным на вашем сервере. Это не то, что когда-либо будет показано пользователю. Статья о HTTP заголовке Feature-Policy
содержит инструкцию по реализации.
let accelerometer = null;
try {
accelerometer = new Accelerometer({ referenceFrame: "device" });
accelerometer.addEventListener("error", (event) => {
// Обработчик ошибок времени исполнения.
if (event.error.name === "NotAllowedError") {
// Переход к коду для запроса разрешения.
} else if (event.error.name === "NotReadableError") {
console.log("Не могу подключиться к датчику.");
}
});
accelerometer.addEventListener("reading", () => reloadOnShake(accelerometer));
accelerometer.start();
} catch (error) {
// Обработчик ошибок создания объекта.
if (error.name === "SecurityError") {
// Смотри заметку о функциональных политиках.
console.log(
"Создание экземпляра объекта датчика было задлокировано по функциональным политикам.",
);
} else if (error.name === "ReferenceError") {
console.log("Датчик не поддерживается в User agent.");
} else {
throw error;
}
}
Разрешения и Функциональные Политики
Показания датчиков могут сниматься только в том случае, если пользователь дает разрешение на определенный тип датчика. Сделать это можно используя Permissions API. Короткий пример, показанный ниже, запрашивает у пользователя разрешение перед попыткой использовать датчик.
navigator.permissions.query({ name: "accelerometer" }).then((result) => {
if (result.state === "denied") {
console.log("Использование датчика не разрешено.");
return;
}
// Используйте датчик.
});
Альтернативный подход заключается в попытке использовать датчик и прослушивании SecurityError
.
const sensor = new AbsoluteOrientationSensor();
sensor.start();
sensor.addEventListener("error", (error) => {
if (event.error.name === "SecurityError")
console.log("Нет разрешения использовать AbsoluteOrientationSensor.");
});
В следующей таблице для каждого типа датчика описано имя, требуемое для Permissions API, атрибут allow
элемента <iframe>
и директива Feature-Policy
.
Датчик | Разрешение/Имя Feature Policy |
---|---|
AbsoluteOrientationSensor |
'accelerometer' , 'gyroscope' , и 'magnetometer' |
Accelerometer |
'accelerometer' |
AmbientLightSensor |
'ambient-light-sensor' |
GravitySensor |
'accelerometer' |
Gyroscope |
'gyroscope' |
LinearAccelerationSensor |
'accelerometer' |
Magnetometer |
'magnetometer' |
RelativeOrientationSensor |
'accelerometer' , и 'gyroscope' |
Показания
Показания датчиков принимаются через событие reading
, которое унаследовано для всех типов датчиков. Частота получения данных зависит от вас и указывается как параметр объекта, переданного в конструктор класса. Этот параметр определяет количество опросов датчика в секунду. Можно использовать целое или десятичное число, последнее для частот менее секунды. Фактическая частота считывания зависит от аппаратного обеспечения устройства и, следовательно, может быть меньше запрошенной.
Пример ниже иллюстрирует это используя Magnetometer
.
let magSensor = new Magnetometer({ frequency: 60 });
magSensor.addEventListener("reading", (e) => {
console.log("Магнитное поле вдоль оси X " + magSensor.x);
console.log("Магнитное поле вдоль оси Y " + magSensor.y);
console.log("Магнитное поле вдоль оси Z " + magSensor.z);
});
magSensor.addEventListener("error", (event) => {
console.log(event.error.name, event.error.message);
});
magSensor.start();
Интерфейсы
AbsoluteOrientationSensor
Secure context-
Описывает физическую ориентацию устройства относительно системы координат Земли.
Accelerometer
Secure context-
Показывает ускорение, приложенное к устройству по всем трём осям.
AmbientLightSensor
Secure context-
Возвращает текущий уровень освещенности или освещенность окружающего освещения вокруг устройства.
GravitySensor
Secure context-
Показывает силу тяжести, приложенную к устройству по всем трём осям.
Gyroscope
Secure context-
Показывает угловую скорость устройства по всем трём осям.
LinearAccelerationSensor
Secure context-
Показывает ускорение, приложенное к устройству по всем трём осям, но без силы тяжести.
Magnetometer
Secure context-
Предоставляет информацию о магнитном поле, обнаруженном основным магнитометром устройства.
OrientationSensor
Secure context-
Базовый класс для
AbsoluteOrientationSensor
. Этот класс не может быть использован сам по себе, вместо этого он предоставляет свойства и методы, к которым обращаются наследуемые от него интерфейсы. RelativeOrientationSensor
Secure context-
Описывает физическую ориентацию устройства без учета системы координат Земли.
Sensor
Secure context-
Базовый класс для всех других интерфесов датчиков. Этот класс не может быть использован сам по себе. Вместо этого он предоставляет свойства, обработчики событий и методы, к которым обращаются интерфейсы, которые наследуются от него.
SensorErrorEvent
Secure context-
Предоставляет информацию об ошибках, вызванных
Sensor
или связанным интерфейсом.
Спецификации
Specification |
---|
Generic Sensor API |
Accelerometer |
Orientation Sensor |
Ambient Light Sensor |
Gyroscope |
Magnetometer |
Совместимость с браузерами
api.Sensor
BCD tables only load in the browser
api.Accelerometer
BCD tables only load in the browser
api.OrientationSensor
BCD tables only load in the browser
api.Gyroscope
BCD tables only load in the browser
api.Magnetometer
BCD tables only load in the browser
api.AmbientLightSensor
BCD tables only load in the browser