uni.startGyroscope在App端未实现,需通过Android Native.js或iOS原生插件获取原始陀螺仪角速度(rad/s);uni.onDeviceMotionChange返回的是延迟高、精度低的姿态角(°),非原始传感器数据。
uni-app 官方 API 在 App 端根本没实现 uni.startGyroscope,调用它不会报错、也不会触发回调——它就是个空函数。真要拿到陀螺仪的角速度(x/y/z rad/s),必须绕过官方封装,走原生通路。
uni.onDeviceMotionChange 不是你要的陀螺仪数据这个 API 返回的是设备姿态角(alpha/beta/gamma),本质是浏览器级融合算法输出,不是原始陀螺仪传感器数据。它:
undefined 或恒定值DeviceMotionEvent,iOS Safari 自 14.5 起默认禁用,需用户手动授权(requestPermission),但 uni-app 无法透出该调用入口TYPE_GYROSCOPE 数据Native.js 是最快验证路径,无需打包原生插件,适合调试和中小项目。关键点:
plus.ready 触发后才能调用,onLoad 阶段 plus.android 还未就绪BODY_SENSORS 权限,仅 ACCESS_FINE_LOCATION 不够sensorManager.getDefaultSensor(3) 返回 null 就代表无硬件(常见于千元机、部分平板)plus.android.implements 实现 SensorEventListener,别硬写字符串;推荐用 SENSOR_DELAY_GAME(约 20ms 间隔)示例片段(简化版):
const main = plus.android.runtimeMainActivity();const Context = plus.android.importClass('android.content.Context');const SensorManager = plus.android.importClass('android.hardware.SensorManager');const sensorManager = main.getSystemService(Context.SENSOR_SERVICE);const gyro = sensorManager.getDefaultSensor(3); // TYPE_GYROSCOPE = 3if (!gyro) { uni.showToast({ title: '设备不支持陀螺仪', icon: 'none' }); return;}const listener = plus.android.implements('android.hardware.SensorEventListener', { onSensorChanged: function(event) { const values = event.plusGetAttribute('values'); console.log('gyro raw:', values[0].toFixed(3), values[1].toFixed(3), values[2].toFixed(3)); // rad/s }, onAccuracyChanged: function() {}});sensorManager.registerListener(listener, gyro, SensorManager.SENSOR_DELAY_GAME);
Native.js 行不通iOS 的 CMMotionManager 不允许 JS 直接反射调用,Native.js 在 iOS 上对传感器类完全不可用。你只能:
nativePlugins/gyro 插件目录,按 uni-app 插件规范导出 start() / stop() / onGyroscopeChange()
NSMotionUsageDescription 字符串,否则 CMMotionManager 初始化失败且无提示startGyroUpdates 启动,数据单位为 rad/s,注意线程:回调在后台线程,需用 dispatch_async 切回主线程再发 JS 事件即使代码全对,以下问题仍会卡住你:
registerListener 会被系统静默取消,且多数厂商 ROM 不允许后台持续采样——必须在 onHide 主动 unregisterListener,并在 onShow 重建unregisterListener 只能注销最后一次注册的实例,其余监听器继续跑,耗电且数据混乱