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