• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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