Sensor APIs

安全上下文: 此功能仅在安全上下文(HTTPS)中可用,且支持此功能的浏览器数量有限。

传感器 API 是一组接口,它们基于通用设计构建,以一致的方式将设备传感器暴露给 Web 平台。

概念与用法

尽管通用传感器 API 规范定义了一个 Sensor 接口,但作为 Web 开发者,您永远不会直接使用它。相反,您将使用它的某个子类来检索特定类型的传感器数据。例如,Accelerometer 接口返回设备在读取时沿三个轴的加速度。

传感器可能对应也可能不完全对应物理设备传感器。例如,Gyroscope 接口完全对应一个物理设备接口。或者,AbsoluteOrientationSensor 接口提供的信息是根据两个或多个设备传感器算法聚合而成的。这些传感器类型分别被称为低级高级。后一种类型的传感器也称为融合传感器(或虚拟传感器、合成传感器)。

特性检测

传感器接口只是底层设备传感器的代理。因此,传感器比其他 API 更难进行特性检测。传感器 API 的存在并不能告诉您该 API 是否连接到真实硬件传感器、该传感器是否正常工作、是否仍然连接,甚至用户是否已授予对其的访问权限。一致地提供所有这些信息会影响性能和电池续航。

因此,传感器 API 的特性检测必须同时包括 API 本身的检测以及 防御性编程策略(见下文)

下面的示例演示了检测传感器 API 的三种方法。此外,您还可以将对象实例化放在 try...catch 块中。请注意,通过 Navigator 接口进行检测不是可用选项之一。

js
if (typeof Gyroscope === "function") {
  // run in circles…
}

if ("ProximitySensor" in window) {
  // watch out!
}

if (window.AmbientLightSensor) {
  // go dark…
}

防御性编程

如特性检测中所述,仅检查特定传感器 API 不足以进行特性检测。还必须确认实际传感器的存在。这时就需要防御性编程。防御性编程需要三种策略。

  • 检查实例化传感器对象时抛出的错误。
  • 监听使用过程中抛出的错误。
  • 优雅地处理错误,从而提升而非降低用户体验。

下面的代码示例说明了这些原则。try...catch 块捕获传感器实例化期间抛出的错误。它监听 error 事件以捕获使用过程中抛出的错误。只有在需要请求 权限 以及设备不支持该传感器类型时,才会向用户显示内容。

此外,此功能可能会被服务器设置的 权限策略 阻止。

js
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 阻止,否则可能无法读取传感器。

下面的示例展示了如何在尝试使用传感器之前请求用户权限。

js
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

js
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'
环境光传感器 'ambient-light-sensor'
GravitySensor 'accelerometer'
Gyroscope 'gyroscope'
LinearAccelerationSensor 'accelerometer'
磁力计 'magnetometer'
RelativeOrientationSensor 'accelerometer''gyroscope'

读数

传感器读数通过所有传感器类型继承的 reading 事件回调接收。读数频率由您决定,通过传递给传感器构造函数的选项来实现。该选项是一个数字,指定每秒的读数次数。可以使用整数或小数,后者用于每秒频率低于 1 的情况。实际读数频率取决于设备硬件,因此可能低于请求的频率。

以下示例使用 Magnetometer 传感器说明了这一点。

js
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

描述设备相对于地球参考坐标系统的物理方向。

加速度计

提供设备沿三个轴施加的加速度。

环境光传感器

返回托管设备周围环境光的当前光照级别或照度。

GravitySensor

提供设备沿三个轴施加的重力。

Gyroscope

提供设备沿三个轴的角速度。

LinearAccelerationSensor

提供设备沿三个轴施加的加速度,但不包含重力的贡献。

磁力计

提供设备主要磁力计传感器检测到的有关磁场的信息。

OrientationSensor

AbsoluteOrientationSensor 的基类。此接口不能直接使用,而是提供由继承它的接口访问的属性和方法。

RelativeOrientationSensor

描述设备相对于地球参考坐标系统的物理方向。

Sensor

所有其他传感器接口的基类。此接口不能直接使用。相反,它提供了由继承它的接口访问的属性、事件处理程序和方法。

SensorErrorEvent

提供有关 Sensor 或相关接口抛出的错误的信息。

规范

规范
通用传感器 API
加速度计
方向传感器
环境光传感器
Gyroscope
磁力计

浏览器兼容性

api.Sensor

api.Accelerometer

api.OrientationSensor

api.Gyroscope

api.Magnetometer

api.AmbientLightSensor