uni-app 无api获取传感器真实刷新频率,uni.getaccelerometerfrequency等仅回显设置值;真机受系统策略影响实际频率常低于设定值,需用时间戳测间隔验证。

uni-app 没有提供直接读取传感器当前实际刷新频率的 API,uni.getAccelerometerFrequency、uni.getGyroscopeFrequency 等函数仅用于「设置」频率,且返回的是你传入的值(或默认值),不是设备真实采样率。
为什么 uni.getAccelerometerFrequency 不返回真实频率
这个函数设计上就是个“回显器”:它不查询硬件,只返回你上次调用 uni.setAccelerometerFrequency 时传的字符串(如 'game'),或者未设置时的默认值 'normal'。真机上 Android 可能因省电策略降频到 10Hz,iOS 可能被 WKWebView 限流到 20Hz,但这些你完全无法通过 JS 层获知。
- 调用后返回
{ frequency: 'game' }≠ 设备真在以 60Hz 运行 - Android 厂商 ROM(如 MIUI、OriginOS)常静默拦截高频率请求,无日志、无报错
- iOS 14.5+ 对
DeviceMotionEvent默认禁用,即使设了'game',底层也只按 10–15Hz 推送
如何间接验证实际采样间隔
唯一可靠方式是自己打时间戳测间隔。必须在 uni.onAccelerometerChange 或 uni.onDeviceMotionChange 回调里做,不能依赖外部计时器。
- 记录每次回调的
Date.now(),与上一次相减,得到真实 ms 间隔 - 连续采集 20 帧以上再算中位数(避免首帧延迟、GC 干扰)
- 注意:Android 真机上若看到间隔稳定在 50ms(20Hz),基本可判定被系统降频;iOS 若长期卡在 100ms(10Hz),大概率是未触发
requestPermission或页面未激活
let lastTime = 0;
uni.onAccelerometerChange(res => {
const now = Date.now();
if (lastTime) {
console.log('interval:', now - lastTime, 'ms');
}
lastTime = now;
});
Native.js 路径下能拿到真实频率吗
可以,但仅限 Android,且需手动查 SensorManager 返回的 minDelay(单位微秒)——这是硬件支持的理论最小间隔,不代表当前生效值。
- 调用
sensorManager.getDefaultSensor(1).getMinDelay()(1 是加速度计类型) - 返回值如
20000表示硬件最低支持 20ms(50Hz),但实际注册监听时传SENSOR_DELAY_GAME后,仍可能被系统覆盖 - iOS 侧无等效接口:
CMMotionManager不暴露底层采样周期,deviceMotionUpdateInterval是你设的期望值,不可读回 - 别试图用
plus.android.invoke(sensor, 'getMaxDelay')—— 多数传感器不实现该方法,会直接报错
容易被忽略的关键点
所谓“当前刷新频率”本身是个伪概念:它由四层动态叠加决定——硬件能力、厂商 ROM 策略、系统电源状态、WebView 实现。你在 JS 层看到的永远只是最上层的“请求值”,而真正落地的采样节奏,连原生代码都未必能 100% 精确控制。做体感交互时,与其纠结频率数字,不如专注处理好数据抖动和时间戳漂移。











