sensors 传感器
sensors 传感器
sensors 是 ScriptX 里对 Android 传感器的一层脚本包装。它既能让你按名称拿传感器对象,也能直接注册监听、统一注销,还额外补了一层“设备不支持某类传感器时怎么办”的处理。
如果你以前没写过 Android 传感器脚本,先记住一句话:
sensors.getSensor(name):拿对象sensors.register(name, delay):拿对象并顺手开始监听- 对象上的
on("change", ...):收数据
先记住这 10 条
- 传感器名称当前按字符串解析,内部会先做
trim().lowercase()。 sensors.getSensor(name)只拿对象,不会自动开始事件监听。sensors.register(name, delay?)会开始监听,并返回对应传感器对象。sensors.unregister(...)可以传名字、原生Sensor、或前面拿到的包装对象。sensors.unregisterAll()会停掉所有已启用的监听。sensors.ignoresUnsupportedSensor = true以后,不支持的传感器不会直接返回null,而是会返回一个“虚拟事件发射器对象”。- 模块对象和每个传感器对象身上都带
on / once / off / removeListener / removeAllListeners / listenerCount / eventNames这一套事件方法。 - 传感器延迟常量既有
SensorDelay.Fastest这种大写写法,也保留了delay.fastest这种小写兼容写法。 - 三轴传感器的
change回调会直接给你(event, x, y, z)。 - 单值传感器的
change回调会直接给你(event, value)。
常见传感器名称
当前实现会优先按 Sensor.TYPE_* 常量名来解析,所以常见可写值包括:
| 名称 | 说明 |
|---|---|
accelerometer | 加速度传感器 |
gyroscope | 陀螺仪 |
light | 光线传感器 |
pressure | 气压传感器 |
proximity | 距离传感器 |
gravity | 重力传感器 |
orientation | 方向传感器 |
magnetic_field | 地磁传感器 |
linear_acceleration | 线性加速度 |
temperature | 温度 / 环境温度兼容名 |
另外还有一种兜底匹配:
- 直接拿系统
sensor.name去忽略大小写匹配 - 或拿
stringType最后一段再把-换成_匹配
所以如果标准短名没命中,也可以试试设备原生名称。
sensors.getSensor(name)
作用
按名称获取一个传感器包装对象,但不自动开始监听事件。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
name | string | 传感器名称;空字符串直接返回 null |
返回值
SensorObject | null
示例
const sensor = sensors.getSensor("accelerometer");
if (!sensor) {
log("当前设备没有 accelerometer");
}
什么时候优先用它
当你想先拿对象、先绑定监听、稍后再手动开启采样时,用这组更顺:
const sensor = sensors.getSensor("light");
if (sensor) {
sensor.on("change", function (event, lux) {
log("lux =", lux);
});
sensor.enableSensorEvent(sensors.SensorDelay.Ui);
}
sensors.register(name, delay?)
作用
按名称拿传感器对象,并立即开始注册监听。
参数
| 参数 | 类型 | 可填值 | 默认值 |
|---|---|---|---|
name | string | 传感器名称 | 无 |
delay | number | 0 / 1 / 2 / 3 | 3 |
返回值
SensorObject | VirtualSensorEmitter | null
delay 对应值
| 值 | 常量 | 含义 |
|---|---|---|
0 | sensors.SensorDelay.Fastest / sensors.delay.fastest | 最高频率 |
1 | sensors.SensorDelay.Game / sensors.delay.game | 游戏级 |
2 | sensors.SensorDelay.Ui / sensors.delay.ui | UI 级 |
3 | sensors.SensorDelay.Normal / sensors.delay.normal | 普通级 |
不是这 4 个值时,当前会回退成 Normal。
示例
const acc = sensors.register("accelerometer", sensors.SensorDelay.Game);
if (acc) {
acc.on("change", function (event, x, y, z) {
log(`acc x=${x} y=${y} z=${z}`);
});
}
为什么有时候会返回 null
| 场景 | 返回值 |
|---|---|
| 名称为空 | null |
当前设备不支持该传感器,且 ignoresUnsupportedSensor=false | null |
没拿到 SensorManager | null |
sensors.unregister(sensorOrNameOrObject)
作用
停止某一个传感器对象的事件监听。
参数支持的形态
| 传法 | 是否支持 | 说明 |
|---|---|---|
| 传字符串名称 | 支持 | 例如 "accelerometer" |
传 sensors.getSensor(...) / register(...) 返回的对象 | 支持 | 最稳 |
传原生 Sensor 对象 | 支持 | 适合你自己保存过原生对象时 |
返回值
boolean
示例 1:按对象注销
const sensor = sensors.register("light");
sleep(3000);
sensors.unregister(sensor);
示例 2:按名称注销
sensors.unregister("accelerometer");
sensors.unregisterAll()
作用
停掉当前脚本下所有已注册的传感器监听。
返回值
boolean
示例
sensors.unregisterAll();
sensors.ignoresUnsupportedSensor
作用
控制当设备不支持某类传感器时,register() 是直接返回 null,还是返回一个虚拟事件对象。
类型
boolean
默认值
false
两种模式的区别
| 值 | 行为 |
|---|---|
false | 不支持时直接返回 null |
true | 不支持时触发模块级 unsupported_sensor 事件,并返回一个虚拟事件发射器对象 |
示例
sensors.ignoresUnsupportedSensor = true;
sensors.on("unsupported_sensor", function (name, sensorType) {
log(`unsupported: ${name}, type=${sensorType}`);
});
const sensor = sensors.register("heart_rate");
log(sensor ? "got virtual emitter or real sensor" : "null");
sensors.SensorDelay
大写常量写法:
log(sensors.SensorDelay.Fastest);
log(sensors.SensorDelay.Game);
log(sensors.SensorDelay.Ui);
log(sensors.SensorDelay.Normal);
sensors.delay
小写兼容写法:
log(sensors.delay.fastest);
log(sensors.delay.game);
log(sensors.delay.ui);
log(sensors.delay.normal);
传感器对象通用事件方法
无论是模块对象、真实传感器对象,还是虚拟传感器对象,当前都接了统一的 emitter 方法:
on(eventName, listener)addListener(eventName, listener)once(eventName, listener)prependListener(eventName, listener)prependOnceListener(eventName, listener)removeListener(eventName, listener)off(eventName, listener)removeAllListeners([eventName])setMaxListeners(count)getMaxListeners()listeners(eventName)rawListeners(eventName)listenerCount(eventName)eventNames()
如果你之前用过 events 或 Node.js 的 EventEmitter,这一套会很熟。
模块级事件:unsupported_sensor
事件名
unsupported_sensor
触发时机
只有在这两个条件同时满足时才会触发:
sensors.ignoresUnsupportedSensor = true- 你调用
sensors.register(name, ...),但设备不支持该传感器
回调参数
| 参数 | 说明 |
|---|---|
name | 你传入的名称 |
sensorType | 解析出来的传感器类型号,解析不到时是 -1 |
示例
sensors.ignoresUnsupportedSensor = true;
sensors.on("unsupported_sensor", function (name, sensorType) {
log(`unsupported sensor: ${name}, type=${sensorType}`);
});
sensors.register("ambient_foo_sensor");
真实传感器对象
通过 getSensor() 或 register() 拿到的真实对象,底层包的是 Android Sensor,并额外接了事件方法和下面这两个控制方法。
sensor.enableSensorEvent(delay?)
作用
手动开启这个传感器的事件监听。
参数
和 register(name, delay?) 的 delay 规则一样,支持 0 / 1 / 2 / 3。
返回值
当前返回传感器对象本身,方便继续链式写法。
示例
const sensor = sensors.getSensor("gyroscope");
if (sensor) {
sensor.on("change", function (event, x, y, z) {
log(`gyro ${x}, ${y}, ${z}`);
});
sensor.enableSensorEvent(sensors.SensorDelay.Game);
}
sensor.disableSensorEvent()
作用
停掉当前这个传感器对象的事件监听。
返回值
传感器对象本身。
示例
sensor.disableSensorEvent();
真实传感器对象事件:change
事件名
change
三轴传感器的参数形态
下面这类传感器会给你:
function (event, x, y, z) {}
当前明确包括:
accelerometermagnetic_fieldorientationgyroscopegravitylinear_acceleration
单值传感器的参数形态
下面这类传感器会给你:
function (event, value) {}
当前明确包括:
lightpressureproximitytemperatureambient_temperature
其他传感器
其他类型当前会给你:
function (event, ...values) {}
也就是把 SensorEvent.values 直接展开出来。
示例 1:三轴
const acc = sensors.register("accelerometer");
if (acc) {
acc.on("change", function (event, x, y, z) {
log(`x=${x} y=${y} z=${z}`);
});
}
示例 2:单值
const light = sensors.register("light", sensors.SensorDelay.Ui);
if (light) {
light.on("change", function (event, lux) {
log(`lux=${lux}`);
});
}
真实传感器对象事件:accuracy_change
事件名
accuracy_change
回调参数
| 参数 | 说明 |
|---|---|
accuracy | Android 原生精度整数值 |
示例
const sensor = sensors.register("magnetic_field");
if (sensor) {
sensor.on("accuracy_change", function (accuracy) {
log(`accuracy=${accuracy}`);
});
}
虚拟传感器对象
当 ignoresUnsupportedSensor = true 且设备不支持该传感器时,register() 返回的是一个虚拟对象。
它有哪些字段
| 字段 | 说明 |
|---|---|
sensorName | 你传入的名称 |
sensorType | 解析得到的类型号,解析不到时为 -1 |
它有哪些方法
- 同样带完整 emitter 方法
enableSensorEvent(...)disableSensorEvent()
但这两个控制方法在虚拟对象上只是返回对象本身,不会真的产生系统传感器数据。
它适合干什么
适合你想把“不支持某传感器”也纳入统一流程,不想每处都手写 if (!sensor) return。
一个完整例子:设备支持就监听,不支持就给提示
sensors.ignoresUnsupportedSensor = true;
sensors.on("unsupported_sensor", function (name, sensorType) {
log(`设备不支持 ${name}, sensorType=${sensorType}`);
});
const light = sensors.register("light", sensors.SensorDelay.Ui);
if (light) {
light.on("change", function (event, lux) {
if (lux < 10) {
log("环境很暗");
} else {
log(`当前亮度: ${lux}`);
}
});
}
一个完整例子:先拿对象,后注册,最后统一关闭
const acc = sensors.getSensor("accelerometer");
const gyro = sensors.getSensor("gyroscope");
if (acc) {
acc.on("change", function (event, x, y, z) {
log(`acc => ${x}, ${y}, ${z}`);
});
acc.enableSensorEvent(sensors.SensorDelay.Game);
}
if (gyro) {
gyro.on("change", function (event, x, y, z) {
log(`gyro => ${x}, ${y}, ${z}`);
});
gyro.enableSensorEvent(sensors.SensorDelay.Game);
}
sleep(5000);
sensors.unregisterAll();
