传感器 API
概念和用法
尽管通用传感器 API 规范定义了一个Sensor
接口,但作为 Web 开发人员,您永远不会使用它。相反,您将使用其子类之一来检索特定类型的传感器数据。例如,Accelerometer
接口在读取时返回设备沿所有三个轴的加速度。
传感器可能与物理设备传感器完全对应,也可能不完全对应。例如,Gyroscope
接口与物理设备接口完全对应。或者,AbsoluteOrientationSensor
接口提供通过算法从两个或多个设备传感器聚合的信息。这些传感器类型分别称为低级和高级。后一种类型的传感器也称为融合传感器(或者,虚拟或合成传感器)。
功能检测
传感器接口只是底层设备传感器的代理。因此,传感器的功能检测比其他 API 更复杂。传感器 API 的存在并不能告诉您该 API 是否连接到真实的硬件传感器,该传感器是否工作,是否仍连接,甚至用户是否已授予访问权限。使所有这些信息始终可用会对性能和电池寿命造成损害。
因此,传感器 API 的功能检测必须包括检测 API 本身和防御性编程策略(见下文)。
以下示例展示了三种检测传感器 API 的方法。此外,您可以将对象实例化放在try...catch
块中。请注意,通过Navigator
接口进行检测不是可用选项之一。
if (typeof Gyroscope === "function") {
// run in circles…
}
if ("ProximitySensor" in window) {
// watch out!
}
if (window.AmbientLightSensor) {
// go dark…
}
防御性编程
如功能检测中所述,检查特定的传感器 API 对于功能检测是不够的。还必须确认实际传感器的存在。这就是需要防御性编程的地方。防御性编程需要三种策略。
- 在实例化传感器对象时检查抛出的错误。
- 侦听在其使用过程中抛出的错误。
- 优雅地处理错误,以便增强用户体验而不是降低用户体验。
下面的代码示例说明了这些原则。try...catch
块捕获在传感器实例化期间抛出的错误。它侦听error
事件以捕获在使用过程中抛出的错误。仅当需要请求权限以及设备不支持传感器类型时,才会向用户显示任何内容。
此外,此功能可能会被服务器上设置的权限策略阻止。
let accelerometer = null;
try {
accelerometer = new Accelerometer({ referenceFrame: "device" });
accelerometer.addEventListener("error", (event) => {
// Handle runtime errors.
if (event.error.name === "NotAllowedError") {
// Branch to code for requesting permission.
} else if (event.error.name === "NotReadableError") {
console.log("Cannot connect to the sensor.");
}
});
accelerometer.addEventListener("reading", () => reloadOnShake(accelerometer));
accelerometer.start();
} catch (error) {
// Handle construction errors.
if (error.name === "SecurityError") {
// See the note above about permissions policy.
console.log("Sensor construction was blocked by a permissions policy.");
} else if (error.name === "ReferenceError") {
console.log("Sensor is not supported by the User Agent.");
} else {
throw error;
}
}
权限和权限策略
除非用户使用权限 API授予对特定传感器类型的权限,并且/或者服务器Permissions-Policy
未阻止访问,否则可能无法获取传感器读数。
以下示例显示了如何在尝试使用传感器之前请求用户权限。
navigator.permissions.query({ name: "accelerometer" }).then((result) => {
if (result.state === "denied") {
console.log("Permission to use accelerometer sensor is denied.");
return;
}
// Use the sensor.
});
另一种方法是尝试使用传感器并侦听SecurityError
。
const sensor = new AbsoluteOrientationSensor();
sensor.start();
sensor.addEventListener("error", (error) => {
if (event.error.name === "SecurityError")
console.log("No permissions to use AbsoluteOrientationSensor.");
});
下表描述了每种传感器类型所需的权限 API 名称、<iframe>
元素的allow
属性和Permissions-Policy
指令。
Sensor | 权限策略名称 |
---|---|
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(`Magnetic field along the X-axis ${magSensor.x}`);
console.log(`Magnetic field along the Y-axis ${magSensor.y}`);
console.log(`Magnetic field along the Z-axis ${magSensor.z}`);
});
magSensor.addEventListener("error", (event) => {
console.log(event.error.name, event.error.message);
});
magSensor.start();
接口
AbsoluteOrientationSensor
-
描述设备相对于地球参考坐标系的物理方向。
Accelerometer
-
提供沿所有三个轴施加到设备的加速度。
AmbientLightSensor
-
返回托管设备周围环境光的当前光照水平或照度。
GravitySensor
-
提供沿所有三个轴施加到设备的重力。
Gyroscope
-
提供设备沿所有三个轴的角速度。
LinearAccelerationSensor
-
提供沿所有三个轴施加到设备的加速度,但不包括重力的影响。
Magnetometer
-
提供有关设备的主磁力计传感器检测到的磁场的信息。
OrientationSensor
-
AbsoluteOrientationSensor
的基类。此接口不能直接使用,而是提供继承自它的接口访问的属性和方法。 RelativeOrientationSensor
-
描述设备的物理方向,而不考虑地球的参考坐标系。
Sensor
-
所有其他传感器接口的基类。此接口不能直接使用。相反,它提供继承自它的接口访问的属性、事件处理程序和方法。
SensorErrorEvent
-
提供有关
Sensor
或相关接口抛出的错误的信息。
规范
规范 |
---|
通用传感器 API |
Accelerometer |
方向传感器 |
环境光传感器 |
Gyroscope |
Magnetometer |
浏览器兼容性
api.Sensor
BCD 表仅在启用 JavaScript 的浏览器中加载。
api.Accelerometer
BCD 表仅在启用 JavaScript 的浏览器中加载。
api.OrientationSensor
BCD 表仅在启用 JavaScript 的浏览器中加载。
api.Gyroscope
BCD 表仅在启用 JavaScript 的浏览器中加载。
api.Magnetometer
BCD 表仅在启用 JavaScript 的浏览器中加载。
api.AmbientLightSensor
BCD 表仅在启用 JavaScript 的浏览器中加载。