• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 传感器开发指导(C/C++)
2<!--Kit: Sensor Service Kit-->
3<!--Subsystem: Sensors-->
4<!--Owner: @dilligencer-->
5<!--Designer: @butterls-->
6<!--Tester: @murphy84-->
7<!--Adviser: @hu-zhiqiong-->
8
9## 场景介绍
10
11当设备需要获取传感器数据时,可以使用sensor模块,例如:通过订阅方向传感器数据感知用户设备当前的朝向,通过订阅计步传感器数据统计用户的步数等。
12
13详细的接口介绍请参考[Sensor接口](../../reference/apis-sensor-service-kit/_sensor.md)。
14
15## 函数说明
16
17| 名称                                                         | 描述                                                         |
18| ------------------------------------------------------------ | ------------------------------------------------------------ |
19| OH_Sensor_GetInfos(Sensor_Info **infos, uint32_t *count)     | 获取设备上所有传感器的信息。                                 |
20| OH_Sensor_Subscribe(const Sensor_SubscriptionId *id, const Sensor_SubscriptionAttribute *attribute, const Sensor_Subscriber *subscriber) | 订阅传感器数据。系统将以指定的频率向用户上报传感器数据。<br/>订阅加速度传感器,需要申请ohos.permission.ACCELEROMETER权限;<br/>订阅陀螺仪传感器,需要申请ohos.permission.GYROSCOPE权限;<br/>订阅计步器相关传感器时,需要申请ohos.permission.ACTIVITY_MOTION权限;<br/>订阅与健康相关的传感器时,比如心率传感器需要申请ohos.permission.READ_HEALTH_DATA权限,否则订阅失败;<br/>订阅其余传感器不需要申请权限。 |
21| OH_Sensor_Unsubscribe(const Sensor_SubscriptionId *id, const Sensor_Subscriber *subscriber) | 取消订阅传感器数据。<br/>取消订阅加速度计传感器,需要申请ohos.permission.ACCELEROMETER权限; <br/>取消订阅陀螺仪传感器,需要申请ohos.permission.GYROSCOPE权限; <br/>取消订阅计步器相关传感器时,需要申请ohos.permission.ACTIVITY_MOTION权限;<br/>取消订阅与健康相关的传感器时,需要申请ohos.permission.READ_HEALTH_DATA权限,否则取消订阅失败。 <br/>取消订阅其余传感器不需要申请权限。 |
22| OH_Sensor_CreateInfos(uint32_t count)                        | 用给定的数字创建一个实例数组,请参考[Sensor_Info](../../reference/apis-sensor-service-kit/_sensor.md#sensor_info)。 |
23| OH_Sensor_DestroyInfos(Sensor_Info **sensors, uint32_t count) | 销毁实例数组并回收内存,请参考[Sensor_Info](../../reference/apis-sensor-service-kit/_sensor.md#sensor_info)。 |
24| OH_SensorInfo_GetName(Sensor_Info *sensor, char *sensorName, uint32_t *length) | 获取传感器名称。                                             |
25| OH_SensorInfo_GetVendorName(Sensor_Info* sensor, char *vendorName, uint32_t *length) | 获取传感器的厂商名称。                                       |
26| OH_SensorInfo_GetType(Sensor_Info* sensor, Sensor_Type *sensorType) | 获取传感器类型。                                             |
27| OH_SensorInfo_GetResolution(Sensor_Info* sensor, float *resolution) | 获取传感器分辨率。                                           |
28| OH_SensorInfo_GetMinSamplingInterval(Sensor_Info* sensor, int64_t *minSamplingInterval) | 获取传感器的最小数据上报间隔。                               |
29| OH_SensorInfo_GetMaxSamplingInterval(Sensor_Info* sensor, int64_t *maxSamplingInterval) | 获取传感器的最大数据上报间隔时间。                           |
30| OH_SensorEvent_GetType(Sensor_Event* sensorEvent, Sensor_Type *sensorType) | 获取传感器类型。                                             |
31| OH_SensorEvent_GetTimestamp(Sensor_Event* sensorEvent, int64_t *timestamp) | 获取传感器数据的时间戳。                                     |
32| OH_SensorEvent_GetAccuracy(Sensor_Event* sensorEvent, Sensor_Accuracy *accuracy) | 获取传感器数据的精度。                                       |
33| OH_SensorEvent_GetData(Sensor_Event* sensorEvent, float **data, uint32_t *length) | 获取传感器数据。<br/>数据的长度和内容依赖于监听的传感器类型,传感器上报的数据格式如下:<br/>1.SENSOR_TYPE_ACCELEROMETER:data[0]、data[1]、data[2]分别表示设备x、y、z轴的加速度分量,单位m/s²;<br/>2.SENSOR_TYPE_GYROSCOPE:data[0]、data[1]、data[2]分别表示设备x、y、z轴的旋转角速度,单位弧度/s;<br/>3.SENSOR_TYPE_AMBIENT_LIGHT:data[0]表示环境光强度,单位lux;从API Version 12开始,将返回两个额外的数据,其中data[1]表示色温,单位kelvin;data[2]表示红外亮度,单位cd/m²;<br/> 4.SENSOR_TYPE_MAGNETIC_FIELD:data[0]、data[1]、data[2]分别表示设备x、y、z轴的地磁分量,单位微特斯拉; <br/>5.SENSOR_TYPE_BAROMETER:data[0]表示气压值,单位hPa;<br/>6.SENSOR_TYPE_HALL:data[0]表示皮套吸合状态,0表示打开,大于0表示吸附;<br/>7.SENSOR_TYPE_PROXIMITY:data[0]表示接近状态,0表示接近,大于0表示远离;<br/>8.SENSOR_TYPE_ORIENTATION:data[0]、data[1]、data[2]分别表示设备绕z、x、y轴的角度,单位度;<br/>9.SENSOR_TYPE_GRAVITY:data[0]、data[1]、data[2]分别表示设备x、y、z轴的重力加速度分量,单位m/s²;<br/>10.SENSOR_TYPE_ROTATION_VECTOR:data[0]、data[1]、data[2]分别表示设备x、y、z轴的旋转角度,单位度,data[3]表示旋转向量元素;<br/>11.SENSOR_TYPE_PEDOMETER_DETECTION:data[0]表示计步检测状态,1表示检测到了步数变化;<br/>12.SENSOR_TYPE_PEDOMETER:data[0]表示步数;<br/>13.SENSOR_TYPE_HEART_RATE:data[0]表示心率数值。 |
34| OH_Sensor_CreateSubscriptionId(void)                         | 创建一个Sensor_SubscriptionId 实例。                         |
35| OH_Sensor_DestroySubscriptionId(Sensor_SubscriptionId *id)   | 销毁Sensor_SubscriptionId 实例并回收内存。                   |
36| OH_SensorSubscriptionId_SetType(Sensor_SubscriptionId* id, const Sensor_Type sensorType) | 设置传感器类型。                                             |
37| OH_Sensor_CreateSubscriptionAttribute(void)                  | 创建Sensor_SubscriptionAttribute实例。                       |
38| OH_Sensor_DestroySubscriptionAttribute(Sensor_SubscriptionAttribute *attribute) | 销毁Sensor_SubscriptionAttribute实例并回收内存。             |
39| OH_SensorSubscriptionAttribute_SetSamplingInterval(Sensor_SubscriptionAttribute* attribute, const int64_t samplingInterval) | 设置传感器数据上报间隔。                                     |
40| OH_Sensor_CreateSubscriber(void)                             | 创建一个Sensor_Subscriber实例。                              |
41| OH_Sensor_DestroySubscriber(Sensor_Subscriber *subscriber)   | 销毁Sensor_Subscriber实例并回收内存。                        |
42| OH_SensorSubscriber_SetCallback(Sensor_Subscriber* subscriber, const Sensor_EventCallback callback) | 设置一个回调函数来上报传感器数据。                           |
43
44
45## 开发步骤
46
47开发步骤以加速度传感器为例。
48
491. 新建一个Native C++工程。
50
51   ![输入图片说明](figures/004.png)
52
532. 配置加速度传感器权限,具体配置方式请参考[声明权限](../../security/AccessToken/declare-permissions.md)。
54
55   ```json
56   "requestPermissions": [
57         {
58           "name": "ohos.permission.ACCELEROMETER"
59         },
60       ]
61   ```
62
633. CMakeLists.txt文件中引入动态依赖库。
64
65   ```c
66   target_link_libraries(entry PUBLIC libace_napi.z.so)
67   target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
68   target_link_libraries(entry PUBLIC libohsensor.so)
69   ```
70
714. 在napi_init.cpp文件中编码,首先导入模块。
72
73   ```c
74   #include "sensors/oh_sensor.h"
75   #include "napi/native_api.h"
76   #include "hilog/log.h"
77   #include <thread>
78   ```
79
805. 定义常量。
81
82   ```c
83   const int GLOBAL_RESMGR = 0xFF00;
84   const char *TAG = "[Sensor]";
85   constexpr Sensor_Type SENSOR_ID { SENSOR_TYPE_ACCELEROMETER };
86   constexpr uint32_t SENSOR_NAME_LENGTH_MAX = 64;
87   constexpr int64_t SENSOR_SAMPLE_PERIOD = 200000000;
88   constexpr int32_t SLEEP_TIME_MS = 1000;
89   constexpr int64_t INVALID_VALUE = -1;
90   constexpr float INVALID_RESOLUTION = -1.0F;
91   Sensor_Subscriber *g_user = nullptr;
92   ```
93
946. 定义一个回调函数用来接收传感器数据。
95
96   ```c
97   void SensorDataCallbackImpl(Sensor_Event *event) {
98       if (event == nullptr) {
99           OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "event is null");
100           return;
101       }
102       int64_t timestamp = INVALID_VALUE;
103       int32_t ret = OH_SensorEvent_GetTimestamp(event, &timestamp); // 获取传感器数据的时间戳。
104       if (ret != SENSOR_SUCCESS) {
105           return;
106       }
107       Sensor_Type sensorType;
108       ret = OH_SensorEvent_GetType(event, &sensorType); // 获取传感器类型。
109       if (ret != SENSOR_SUCCESS) {
110           return;
111       }
112       Sensor_Accuracy accuracy = SENSOR_ACCURACY_UNRELIABLE;
113       ret = OH_SensorEvent_GetAccuracy(event, &accuracy); // 获取传感器数据的精度。
114       if (ret != SENSOR_SUCCESS) {
115           return;
116       }
117       float *data = nullptr;
118       uint32_t length = 0;
119       ret = OH_SensorEvent_GetData(event, &data, &length); // 获取传感器数据。
120       if (ret != SENSOR_SUCCESS) {
121           return;
122       }
123       if (data == nullptr) {
124           return;
125       }
126       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "sensorType:%{public}d, dataLen:%{public}d, accuracy:%{public}d", sensorType, length, accuracy);
127       for (uint32_t i = 0; i < length; ++i) {
128           OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "data[%{public}d]:%{public}f", i, data[i]);
129       }
130   }
131   ```
132
1337. 获取设备上所有传感器的信息。
134
135   ```c
136   static napi_value GetSensorInfos(napi_env env, napi_callback_info info)
137   {
138       uint32_t count = 0;
139       int32_t ret = OH_Sensor_GetInfos(nullptr, &count); // 获取设备上所有传感器的个数。
140       if (ret != SENSOR_SUCCESS) {
141           return nullptr;
142       }
143       Sensor_Info **sensors = OH_Sensor_CreateInfos(count); // 用给定的数字创建一个实例数组。
144       if (sensors == nullptr) {
145           return nullptr;
146       }
147       ret = OH_Sensor_GetInfos(sensors, &count); // 获取设备上所有传感器的信息。
148       if (ret != SENSOR_SUCCESS) {
149           return nullptr;
150       }
151       for (uint32_t i = 0; i < count; ++i) {
152           char sensorName[SENSOR_NAME_LENGTH_MAX] = {};
153           uint32_t length = SENSOR_NAME_LENGTH_MAX;
154           ret = OH_SensorInfo_GetName(sensors[i], sensorName, &length); // 获取传感器名称。
155           if (ret != SENSOR_SUCCESS) {
156               return nullptr;
157           }
158           char vendorName[SENSOR_NAME_LENGTH_MAX] = {};
159           length = SENSOR_NAME_LENGTH_MAX;
160           ret = OH_SensorInfo_GetVendorName(sensors[i], vendorName, &length); // 获取传感器的厂商名称。
161           if (ret != SENSOR_SUCCESS) {
162               return nullptr;
163           }
164           Sensor_Type sensorType;
165           ret = OH_SensorInfo_GetType(sensors[i], &sensorType); // 获取传感器类型。
166           if (ret != SENSOR_SUCCESS) {
167               return nullptr;
168           }
169           float resolution = INVALID_RESOLUTION;
170           ret = OH_SensorInfo_GetResolution(sensors[i], &resolution); // 获取传感器分辨率。
171           if (ret != SENSOR_SUCCESS) {
172               return nullptr;
173           }
174           int64_t minSamplePeriod = INVALID_VALUE;
175           ret = OH_SensorInfo_GetMinSamplingInterval(sensors[i], &minSamplePeriod); // 获取传感器的最小数据上报间隔。
176           if (ret != SENSOR_SUCCESS) {
177               return nullptr;
178           }
179           int64_t maxSamplePeriod = INVALID_VALUE;
180           ret = OH_SensorInfo_GetMaxSamplingInterval(sensors[i], &maxSamplePeriod); // 获取传感器的最大数据上报间隔时间。
181           if (ret != SENSOR_SUCCESS) {
182               return nullptr;
183           }
184       }
185       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "GetSensorInfos successful");
186       ret = OH_Sensor_DestroyInfos(sensors, count); // 销毁实例数组并回收内存。
187       if (ret != SENSOR_SUCCESS) {
188           return nullptr;
189       }
190       napi_value result = nullptr;
191       napi_create_int32(env, ret, &result);
192       return result;
193   }
194   ```
195
1968. 订阅和取消订阅传感器数据。
197
198   ```c
199   static napi_value Subscriber(napi_env env, napi_callback_info info)
200   {
201       g_user = OH_Sensor_CreateSubscriber();                                         // 创建一个Sensor_Subscriber实例。
202       int32_t ret = OH_SensorSubscriber_SetCallback(g_user, SensorDataCallbackImpl); // 设置一个回调函数来报告传感器数据。
203       if (ret != SENSOR_SUCCESS) {
204           return nullptr;
205       }
206
207       Sensor_SubscriptionId *id = OH_Sensor_CreateSubscriptionId(); // 创建一个Sensor_SubscriptionId实例。
208       ret = OH_SensorSubscriptionId_SetType(id, SENSOR_ID);         // 设置传感器类型。
209       if (ret != SENSOR_SUCCESS) {
210           return nullptr;
211       }
212
213       Sensor_SubscriptionAttribute *attr = OH_Sensor_CreateSubscriptionAttribute();     // 创建Sensor_SubscriptionAttribute实例。
214       ret = OH_SensorSubscriptionAttribute_SetSamplingInterval(attr, SENSOR_SAMPLE_PERIOD); // 设置传感器数据报告间隔。
215       if (ret != SENSOR_SUCCESS) {
216           return nullptr;
217       }
218
219       ret = OH_Sensor_Subscribe(id, attr, g_user); // 订阅传感器数据。
220       if (ret != SENSOR_SUCCESS) {
221           return nullptr;
222       }
223       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "Subscriber successful");
224       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS));
225       ret = OH_Sensor_Unsubscribe(id, g_user); // 取消订阅传感器数据。
226       if (ret != SENSOR_SUCCESS) {
227           return nullptr;
228       }
229       if (id != nullptr) {
230           OH_Sensor_DestroySubscriptionId(id); // 销毁Sensor_SubscriptionId实例并回收内存。
231       }
232       if (attr != nullptr) {
233           OH_Sensor_DestroySubscriptionAttribute(attr); // 销毁Sensor_SubscriptionAttribute实例并回收内存。
234       }
235       if (g_user != nullptr) {
236           OH_Sensor_DestroySubscriber(g_user); // 销毁Sensor_Subscriber实例并回收内存。
237           g_user = nullptr;
238       }
239       napi_value result = nullptr;
240       napi_create_int32(env, ret, &result);
241       return result;
242   }
243   ```
244
2459. 在Init函数中补充接口。
246
247   ```c
248   EXTERN_C_START
249   static napi_value Init(napi_env env, napi_value exports)
250   {
251       napi_property_descriptor desc[] = {
252           { "getSensorInfos", nullptr, GetSensorInfos, nullptr, nullptr, nullptr, napi_default, nullptr },
253           { "subscriber", nullptr, Subscriber, nullptr, nullptr, nullptr, napi_default, nullptr }
254       };
255       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
256       return exports;
257   }
258   EXTERN_C_END
259   ```
260
26110. 在types/libentry路径下index.d.ts文件中引入Napi接口。
262
263    ```c
264     export const getSensorInfos: () => number;
265     export const subscriber: () => number;
266    ```
267
26811. 删除Index.ets中的已废弃函数。
269
270    ```js
271    .onClick(() => {
272        hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3));
273    })
274    ```
275