1# 使用运动和方向传感器监测设备状态 2 3## 概述 4 5运动和方向传感器,如加速度计、陀螺仪等,能够监测设备的运动状态和方向变化,例如设备的旋转、倾斜等。 6通过W3C标准协议接口,Web组件能够访问这些传感器的数据,进而实现更加丰富的用户交互功能。例如,开发者在网页应用中可以利用加速度计识别运动模式,指导用户进行健身运动,利用陀螺仪捕获玩家手中设备的倾斜和旋转动作,实现无按钮操控的游戏体验。 7 8通过在JavaScript中调用以下支持的W3C标准协议接口,可以访问运动和方向传感器。 9 10| 接口 | 名称 | 说明 | 11| ------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | 12| Accelerometer | 加速度 | 可获取设备X、Y、Z轴方向的加速度数据。 | 13| Gyroscope | 陀螺仪 | 可获取设备X、Y、Z轴方向的角速度数据。 | 14| AbsoluteOrientationSensor | 绝对定位 | 可获取表示设备绝对定位方向的四元数,包含X、Y、Z和W分量。 | 15| RelativeOrientationSensor | 相对定位 | 可获取表示设备相对定位方向的四元数,包含X、Y、Z和W分量。 | 16| DeviceMotionEvent | 设备运动事件 | 通过监听该事件,可获取设备在X、Y、Z轴方向上的加速度数据,设备在X、Y、Z轴方向上包含重力的加速度数据,以及设备在alpha、beta、gamma轴方向上旋转的速率数据。 | 17| DeviceOrientationEvent | 设备方向事件 | 通过监听该事件,可获取设备绕X、Y、Z轴的角度。 | 18 19## 需要权限 20 21使用加速度、陀螺仪及设备运动事件接口时,需在配置文件module.json5中声明相应的传感器权限。具体配置方法请参考[在配置文件中声明权限](../security/AccessToken/declare-permissions.md)。 22 23``` 24 "requestPermissions":[ 25 { 26 "name" : "ohos.permission.ACCELEROMETER" // 加速度权限 27 }, 28 { 29 "name" : "ohos.permission.GYROSCOPE" // 陀螺仪权限 30 } 31 ] 32``` 33 34Web组件在对接运动和方向传感器时,需配置[onPermissionRequest](../reference/apis-arkweb/ts-basic-components-web.md#onpermissionrequest9)接口,通过该接口接收权限请求通知。 35 36## 开发步骤 37 381. 应用侧代码中,Web组件配置[onPermissionRequest](../reference/apis-arkweb/ts-basic-components-web.md#onpermissionrequest9)接口,可通过[PermissionRequest](../reference/apis-arkweb/ts-basic-components-web.md#permissionrequest9)的[getAccessibleResource](../reference/apis-arkweb/ts-basic-components-web.md#getaccessibleresource9)接口获取请求权限的资源类型,当资源类型为TYPE_SENSOR时,进行传感器授权处理。 39 40 ```ts 41 import { webview } from '@kit.ArkWeb'; 42 import { abilityAccessCtrl, PermissionRequestResult } from '@kit.AbilityKit'; 43 import { BusinessError } from '@kit.BasicServicesKit'; 44 45 @Entry 46 @Component 47 struct WebComponent { 48 controller: webview.WebviewController = new webview.WebviewController(); 49 uiContext: UIContext = this.getUIContext(); 50 51 aboutToAppear() { 52 // 配置Web开启调试模式 53 webview.WebviewController.setWebDebuggingAccess(true); 54 // 访问控制管理, 获取访问控制模块对象。 55 let atManager = abilityAccessCtrl.createAtManager(); 56 try { 57 atManager.requestPermissionsFromUser(this.uiContext.getHostContext(), ['ohos.permission.ACCELEROMETER', 'ohos.permission.GYROSCOPE'] 58 , (err: BusinessError, data: PermissionRequestResult) => { 59 console.info('data:' + JSON.stringify(data)); 60 console.info('data permissions:' + data.permissions); 61 console.info('data authResults:' + data.authResults); 62 }) 63 } catch (error) { 64 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 65 } 66 } 67 68 build() { 69 Column() { 70 Web({ src: $rawfile('index.html'), controller: this.controller }) 71 .onPermissionRequest((event) => { 72 if (event) { 73 this.uiContext.showAlertDialog({ 74 title: 'title', 75 message: 'text', 76 primaryButton: { 77 value: 'deny', 78 action: () => { 79 event.request.deny(); 80 } 81 }, 82 secondaryButton: { 83 value: 'onConfirm', 84 action: () => { 85 event.request.grant(event.request.getAccessibleResource()); 86 } 87 }, 88 autoCancel: false, 89 cancel: () => { 90 event.request.deny(); 91 } 92 }) 93 } 94 }) 95 } 96 } 97 } 98 ``` 99 1002. 在前端页面代码中,利用JavaScript调用传感器相关的W3C标准协议接口。 101 102 ```html 103 <!DOCTYPE HTML> 104 <html> 105 <head> 106 <meta charset="utf-8" /> 107 <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 108 <meta name="misapplication-tap-highlight" content="no" /> 109 <meta name="HandheldFriendly" content="true" /> 110 <meta name="MobileOptimized" content="320" /> 111 <title>运动和方向传感器</title> 112 <meta charset="UTF-8"> 113 <style> 114 body { 115 font-family: Arial, sans-serif; 116 } 117 </style> 118 <script type="text/javascript"> 119 // 访问设备的加速度计传感器,并获取其数据。 120 function getAccelerometer() { 121 var acc = new Accelerometer({frequency: 60}); 122 acc.addEventListener('activate', () => console.log('Ready to measure.')); 123 acc.addEventListener('error', error => console.log('Error type: ' + error.type + ', error: ' + error.error )); 124 acc.addEventListener('reading', () => { 125 console.log(`Accelerometer ${acc.timestamp}, ${acc.x}, ${acc.y}, ${acc.z}.`); 126 }); 127 acc.start(); 128 } 129 130 // 访问设备的陀螺仪传感器,并获取其数据。 131 function getGyroscope() { 132 var gyr = new Gyroscope({frequency: 60}); 133 gyr.addEventListener('activate', () => console.log('Ready to measure.')); 134 gyr.addEventListener('error', error => console.log('Error type: ' + error.type + ', error: ' + error.error )); 135 gyr.addEventListener('reading', () => { 136 console.log(`Gyroscope ${gyr.timestamp}, ${gyr.x}, ${gyr.y}, ${gyr.z}.`); 137 }); 138 gyr.start(); 139 } 140 141 // 访问设备的方向传感器,并获取其数据。 142 function getAbsoluteOrientationSensor() { 143 var aos = new AbsoluteOrientationSensor({frequency: 60}); 144 aos.addEventListener('activate', () => console.log('Ready to measure.')); 145 aos.addEventListener('error', error => console.log('Error type: ' + error.type + ', error: ' + error.error )); 146 aos.addEventListener('reading', () => { 147 console.log(`AbsoluteOrientationSensor data: ${aos.timestamp}, ${aos.quaternion}`); 148 }); 149 aos.start(); 150 } 151 152 // 监听设备的运动事件,并执行相应的处理逻辑。 153 function listenDeviceMotionEvent() { 154 removeDeviceMotionEvent(); 155 if ('DeviceMotionEvent' in window) { 156 window.addEventListener('devicemotion', handleMotionEvent, false); 157 } else { 158 console.log('不支持DeviceMotionEvent'); 159 } 160 } 161 162 // 移除之前添加的设备运动事件监听器。 163 function removeDeviceMotionEvent() { 164 if ('DeviceMotionEvent' in window) { 165 window.removeEventListener('devicemotion', handleMotionEvent, false); 166 } else { 167 console.log('不支持DeviceOrientationEvent'); 168 } 169 } 170 171 // 处理运动事件。 172 function handleMotionEvent(event) { 173 const x = event.accelerationIncludingGravity.x; 174 const y = event.accelerationIncludingGravity.y; 175 const z = event.accelerationIncludingGravity.z; 176 console.log(`DeviceMotionEvent data: ${event.timeStamp}, ${x}, ${y}, ${z}`); 177 } 178 179 // 监听设备方向的变化,并执行相应的处理逻辑。 180 function listenDeviceOrientationEvent() { 181 removeDeviceOrientationEvent(); 182 if ('DeviceOrientationEvent' in window) { 183 window.addEventListener('deviceorientation', handleOrientationEvent, false); 184 } else { 185 console.log('不支持DeviceOrientationEvent'); 186 } 187 } 188 189 // 移除之前添加的设备方向事件监听器。 190 function removeDeviceOrientationEvent() { 191 if ('DeviceOrientationEvent' in window) { 192 window.removeEventListener('deviceorientation', handleOrientationEvent, false); 193 } else { 194 console.log('不支持DeviceOrientationEvent'); 195 } 196 } 197 198 // 监听设备方向的变化,并执行相应的处理逻辑。 199 function listenDeviceOrientationEvent2() { 200 removeDeviceOrientationEvent2(); 201 if ('DeviceOrientationEvent' in window) { 202 window.addEventListener('deviceorientationabsolute', handleOrientationEvent, false); 203 } else { 204 console.log('不支持DeviceOrientationEvent'); 205 } 206 } 207 208 // 移除之前添加的设备方向事件监听器。 209 function removeDeviceOrientationEvent2() { 210 if ('DeviceOrientationEvent' in window) { 211 window.removeEventListener('deviceorientationabsolute', handleOrientationEvent, false); 212 } else { 213 console.log('不支持DeviceOrientationEvent'); 214 } 215 } 216 217 // 处理方向事件。 218 function handleOrientationEvent(event) { 219 console.log(`DeviceOrientationEvent data: ${event.timeStamp}, ${event.absolute}, ${event.alpha}, ${event.beta}, ${event.gamma}`); 220 } 221 </script> 222 </head> 223 <body> 224 <div id="dcontent" class="dcontent"> 225 <h3>运动和方向:</h3> 226 <ul class="dlist"> 227 <li><button type="button" onclick="getAccelerometer()">加速度</button></li> 228 <li><button type="button" onclick="getGyroscope()">陀螺仪</button></li> 229 <li><button type="button" onclick="getAbsoluteOrientationSensor()">设备方向(绝对定位)</button></li> 230 <li><button type="button" onclick="listenDeviceMotionEvent()">设备运动事件</button></li> 231 <li><button type="button" onclick="listenDeviceOrientationEvent()">设备方向事件</button></li> 232 <li><button type="button" onclick="listenDeviceOrientationEvent2()">设备方向事件(绝对定位)</button></li> 233 </ul> 234 </div> 235 </body> 236 </html> 237 ``` 238