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