1# Sensor Development (C/C++)
2
3
4## When to Use
5
6With the sensor module, a device can obtain sensor data. For example, the device can subscribe to data of the orientation sensor to detect its own orientation, and data of the pedometer sensor to learn the number of steps the user walks every day.
7
8For details about the APIs, see [Sensor API Reference](../../reference/apis-sensor-service-kit/_sensor.md).
9
10## Function Description
11
12| Name                                                        | Description                                                        |
13| ------------------------------------------------------------ | ------------------------------------------------------------ |
14| OH_Sensor_GetInfos(Sensor_Info **infos, uint32_t *count)     | Obtains information about all sensors on the device.                                |
15| OH_Sensor_Subscribe(const Sensor_SubscriptionId *id, const Sensor_SubscriptionAttribute *attribute, const Sensor_Subscriber *subscriber) | Subscribe to sensor data. The system will report sensor data to the subscriber at the specified frequency.<br>To subscribe to data of acceleration sensors, request the **ohos.permission.ACCELEROMETER** permission.<br>To subscribe to data of gyroscope sensors, request the **ohos.permission.GYROSCOPE** permission.<br>To subscribe to data of pedometer-related sensors, request the **ohos.permission.ACTIVITY_MOTION** permission.<br>To subscribe to data of health-related sensors, such as heart rate sensors, request the **ohos.permission.READ_HEALTH_DATA** permission. Otherwise, the subscription fails.<br>You do not need to request any permission to subscribe to data of other types of sensors.|
16| OH_Sensor_Unsubscribe(const Sensor_SubscriptionId *id, const Sensor_Subscriber *subscriber) | Unsubscribes from sensor data.<br>To unsubscribe from data of acceleration sensors, request the **ohos.permission.ACCELEROMETER** permission.<br>To unsubscribe from data of gyroscope sensors, request the **ohos.permission.GYROSCOPE** permission.<br>To unsubscribe from data of pedometer-related sensors, request the **ohos.permission.ACTIVITY_MOTION** permission.<br>To unsubscribe from data of health-related sensors, request the **ohos.permission.READ_HEALTH_DATA** permission. Otherwise, the unsubscription fails.<br>You do not need to request any permission to unsubscribe from data of other types of sensors.|
17| OH_Sensor_CreateInfos(uint32_t count)                        | Creates an array of instances with the given number. For details, see [Sensor_Info](../../reference/apis-sensor-service-kit/_sensor.md#sensor_info).|
18| OH_Sensor_DestroyInfos(Sensor_Info **sensors, uint32_t count) | Destroys the array of instances and reclaims the memory. For details, see [Sensor_Info](../../reference/apis-sensor-service-kit/_sensor.md#sensor_info).|
19| OH_SensorInfo_GetName(Sensor_Info *sensor, char *sensorName, uint32_t *length) | Obtains the sensor name.                                            |
20| OH_SensorInfo_GetVendorName(Sensor_Info* sensor, char *vendorName, uint32_t *length) | Obtains the sensor's vendor name.                                      |
21| OH_SensorInfo_GetType(Sensor_Info* sensor, Sensor_Type *sensorType) | Obtains the sensor type.                                            |
22| OH_SensorInfo_GetResolution(Sensor_Info* sensor, float *resolution) | Obtains the sensor resolution.                                          |
23| OH_SensorInfo_GetMinSamplingInterval(Sensor_Info* sensor, int64_t *minSamplingInterval) | Obtains the minimum data reporting interval of a sensor.                              |
24| OH_SensorInfo_GetMaxSamplingInterval(Sensor_Info* sensor, int64_t *maxSamplingInterval) | Obtains the maximum data reporting interval of a sensor.                          |
25| OH_SensorEvent_GetType(Sensor_Event* sensorEvent, Sensor_Type *sensorType) | Obtains the sensor type.                                            |
26| OH_SensorEvent_GetTimestamp(Sensor_Event* sensorEvent, int64_t *timestamp) | Obtains the timestamp of sensor data.                                    |
27| OH_SensorEvent_GetAccuracy(Sensor_Event* sensorEvent, Sensor_Accuracy *accuracy) | Obtains the accuracy of sensor data.                                      |
28| OH_SensorEvent_GetData(Sensor_Event* sensorEvent, float **data, uint32_t *length) | Obtains sensor data.<br>The data length and content depend on the sensor type. The format of the sensor data reported is as follows:<br>- SENSOR_TYPE_ACCELEROMETER: data[0], data[1], and data[2], indicating the acceleration around the x, y, and z axes of a device, respectively, in m/s².<br>- SENSOR_TYPE_GYROSCOPE: data[0], data[1], and data[2], indicating the angular velocity of rotation around the x, y, and z axes of a device, respectively, in rad/s.<br>- SENSOR_TYPE_AMBIENT_LIGHT: data[0], indicating the ambient light intensity, in lux. Since API version 12, two extra data records are returned, where **data[1]** indicates the color temperature (in kelvin), and **data[2]** indicates the infrared luminance (in cd/m²).<br> - SENSOR_TYPE_MAGNETIC_FIELD: data[0], data[1], and data[2], indicating the magnetic field strength around the x, y, and z axes of a device, respectively, in μT.<br>- SENSOR_TYPE_BAROMETER: data[0], indicating the atmospheric pressure, in hPa.<br>- SENSOR_TYPE_HALL: data[0], indicating the opening/closing state of the flip cover. The value **0** means that the flip cover is opened, and a value greater than 0 means that the flip cover is closed.<br>- SENSOR_TYPE_PROXIMITY: data[0], indicates the approaching state. The value **0** means the two objects are close to each other, and a value greater than 0 means that they are far away from each other.<br>- SENSOR_TYPE_ORIENTATION: data[0], data[1], and data[2], indicating the rotation angles of a device around the z, x, and y axes, respectively, in degree.<br>- SENSOR_TYPE_GRAVITY: data[0], data[1], and data[2], indicating the gravitational acceleration around the x, y, and z axes of a device, respectively, in m/s².<br>- SENSOR_TYPE_ROTATION_VECTOR: data[0], data[1] and data[2], indicating the rotation angles of a device around the x, y, and z axes, respectively, in degree. data[3] indicates the rotation vector.<br>- SENSOR_TYPE_PEDOMETER_DETECTION: data[0], indicating the pedometer detection status. The value **1** means that the number of detected steps changes.<br>- SENSOR_TYPE_PEDOMETER: data[0], indicating the number of steps a user has walked.<br>- SENSOR_TYPE_HEART_RATE: data[0], indicating the heart rate value.|
29| OH_Sensor_CreateSubscriptionId(void)                         | Creates a **Sensor_SubscriptionId** instance.                        |
30| OH_Sensor_DestroySubscriptionId(Sensor_SubscriptionId *id)   | Destroys a **Sensor_SubscriptionId** instance and reclaims memory.                  |
31| OH_SensorSubscriptionId_SetType(Sensor_SubscriptionId* id, const Sensor_Type sensorType) | Sets the sensor type.                                            |
32| OH_Sensor_CreateSubscriptionAttribute(void)                  | Creates a **Sensor_SubscriptionAttribute** instance.                      |
33| OH_Sensor_DestroySubscriptionAttribute(Sensor_SubscriptionAttribute *attribute) | Destroys a **Sensor_SubscriptionAttribute** instance and reclaims memory.            |
34| OH_SensorSubscriptionAttribute_SetSamplingInterval(Sensor_SubscriptionAttribute* attribute, const int64_t samplingInterval) | Sets the interval for reporting sensor data.                                    |
35| OH_Sensor_CreateSubscriber(void)                             | Creates a **Sensor_Subscriber** instance.                             |
36| OH_Sensor_DestroySubscriber(Sensor_Subscriber *subscriber)   | Destroys a **Sensor_Subscriber** instance and reclaims memory.                       |
37| OH_SensorSubscriber_SetCallback(Sensor_Subscriber* subscriber, const Sensor_EventCallback callback) | Sets a callback function to report sensor data.                          |
38
39
40## How to Develop
41
42The following uses the acceleration sensor as an example to describe the development procedure.
43
441. Create a native C++ project.
45
46   ![Create a project](figures/004.png)
47
482. Configure the acceleration sensor permission. For details, see [Declaring Permissions](../../security/AccessToken/declare-permissions.md).
49
50   ```json
51   "requestPermissions": [
52         {
53           "name": "ohos.permission.ACCELEROMETER",
54         },
55       ]
56   ```
57
583. Add the dynamic dependency libraries into the **CMakeLists.txt** file.
59
60   ```c
61   target_link_libraries(entry PUBLIC libace_napi.z.so)
62   target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
63   target_link_libraries(entry PUBLIC libohsensor.so)
64   ```
65
664. Write the **napi_init.cpp** file to import related modules.
67
68   ```c
69   #include "sensors/oh_sensor.h"
70   #include "napi/native_api.h"
71   #include "hilog/log.h"
72   #include <thread>
73   ```
74
755. Define constants.
76
77   ```c
78   const int GLOBAL_RESMGR = 0xFF00;
79   const char *TAG = "[Sensor]";
80   constexpr Sensor_Type SENSOR_ID { SENSOR_TYPE_ACCELEROMETER };
81   constexpr uint32_t SENSOR_NAME_LENGTH_MAX = 64;
82   constexpr int64_t SENSOR_SAMPLE_PERIOD = 200000000;
83   constexpr int32_t SLEEP_TIME_MS = 1000;
84   constexpr int64_t INVALID_VALUE = -1;
85   constexpr float INVALID_RESOLUTION = -1.0F;
86   Sensor_Subscriber *g_user = nullptr;
87   ```
88
896. Define a callback function to receive sensor data.
90
91   ```c
92   void SensorDataCallbackImpl(Sensor_Event *event) {
93       if (event == nullptr) {
94           OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "event is null");
95           return;
96       }
97       int64_t timestamp = INVALID_VALUE;
98       int32_t ret = OH_SensorEvent_GetTimestamp(event, &timestamp); // Obtain the timestamp of sensor data.
99       if (ret != SENSOR_SUCCESS) {
100           return;
101       }
102       Sensor_Type sensorType;
103       ret = OH_SensorEvent_GetType(event, &sensorType); // Obtain the sensor type.
104       if (ret != SENSOR_SUCCESS) {
105           return;
106       }
107       Sensor_Accuracy accuracy = SENSOR_ACCURACY_UNRELIABLE;
108       ret = OH_SensorEvent_GetAccuracy(event, &accuracy); // Obtain the accuracy of sensor data.
109       if (ret != SENSOR_SUCCESS) {
110           return;
111       }
112       float *data = nullptr;
113       uint32_t length = 0;
114       ret = OH_SensorEvent_GetData(event, &data, &length); // Obtain sensor data.
115       if (ret != SENSOR_SUCCESS) {
116           return;
117       }
118       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "sensorType:%{public}d, dataLen:%{public}d, accuracy:%{public}d", sensorType, length, accuracy);
119       for (uint32_t i = 0; i < length; ++i) {
120           OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "data[%{public}d]:%{public}f", i, data[i]);
121       }
122   }
123   ```
124
1257. Obtain information about all sensors on the device.
126
127   ```c
128   static napi_value GetSensorInfos(napi_env env, napi_callback_info info)
129   {
130       uint32_t count = 0;
131       int32_t ret = OH_Sensor_GetInfos(nullptr, &count); // Obtain the number of all sensors on the device.
132       if (ret != SENSOR_SUCCESS) {
133           return nullptr;
134       }
135       Sensor_Info **sensors = OH_Sensor_CreateInfos(count); // Create an array of instances with the given number.
136       if (sensors == nullptr) {
137           return nullptr;
138       }
139       ret = OH_Sensor_GetInfos(sensors, &count); // Obtain information about all sensors on the device.
140       if (ret != SENSOR_SUCCESS) {
141           return nullptr;
142       }
143       for (uint32_t i = 0; i < count; ++i) {
144           char sensorName[SENSOR_NAME_LENGTH_MAX] = {};
145           uint32_t length = SENSOR_NAME_LENGTH_MAX;
146           ret = OH_SensorInfo_GetName(sensors[i], sensorName, &length); // Obtain the sensor name.
147           if (ret != SENSOR_SUCCESS) {
148               return nullptr;
149           }
150           char vendorName[SENSOR_NAME_LENGTH_MAX] = {};
151           length = SENSOR_NAME_LENGTH_MAX;
152           ret = OH_SensorInfo_GetVendorName(sensors[i], vendorName, &length); // Obtain the manufacturer name of the sensor.
153           if (ret != SENSOR_SUCCESS) {
154               return nullptr;
155           }
156           Sensor_Type sensorType;
157           ret = OH_SensorInfo_GetType(sensors[i], &sensorType); // Obtain the sensor type.
158           if (ret != SENSOR_SUCCESS) {
159               return nullptr;
160           }
161           float resolution = INVALID_RESOLUTION;
162           ret = OH_SensorInfo_GetResolution(sensors[i], &resolution); // Obtain the sensor resolution.
163           if (ret != SENSOR_SUCCESS) {
164               return nullptr;
165           }
166           int64_t minSamplePeriod = INVALID_VALUE;
167           ret = OH_SensorInfo_GetMinSamplingInterval(sensors[i], &minSamplePeriod); // Obtain the minimum data reporting interval of a sensor.
168           if (ret != SENSOR_SUCCESS) {
169               return nullptr;
170           }
171           int64_t maxSamplePeriod = INVALID_VALUE;
172           ret = OH_SensorInfo_GetMaxSamplingInterval(sensors[i], &maxSamplePeriod); // Obtain the maximum data reporting interval of a sensor.
173           if (ret != SENSOR_SUCCESS) {
174               return nullptr;
175           }
176       }
177       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "GetSensorInfos sucessful");
178       ret = OH_Sensor_DestroyInfos(sensors, count); // Destroy an array of instances and reclaim the memory.
179       if (ret != SENSOR_SUCCESS) {
180           return nullptr;
181       }
182   }
183   ```
184
1858. Subscribe to and unsubscribe from sensor data.
186
187   ```c
188   static napi_value Subscriber(napi_env env, napi_callback_info info)
189   {
190       g_user = OH_Sensor_CreateSubscriber();                                         // Create a Sensor_Subscriber instance.
191       int32_t ret = OH_SensorSubscriber_SetCallback(g_user, SensorDataCallbackImpl); // Set a callback function to report sensor data.
192       if (ret != SENSOR_SUCCESS) {
193           return nullptr;
194       }
195
196       Sensor_SubscriptionId *id = OH_Sensor_CreateSubscriptionId(); // Create a Sensor_SubscriptionId instance.
197       ret = OH_SensorSubscriptionId_SetType(id, SENSOR_ID); // Set the sensor type.
198       if (ret != SENSOR_SUCCESS) {
199           return nullptr;
200       }
201
202       Sensor_SubscriptionAttribute *attr = OH_Sensor_CreateSubscriptionAttribute(); // Create a Sensor_SubscriptionAttribute instance.
203       ret = OH_SensorSubscriptionAttribute_SetSamplingInterval(attr, SENSOR_SAMPLE_PERIOD); // Set the interval for reporting sensor data.
204       if (ret != SENSOR_SUCCESS) {
205           return nullptr;
206       }
207
208       ret = OH_Sensor_Subscribe(id, attr, g_user); // Subscribe to sensor data.
209       if (ret != SENSOR_SUCCESS) {
210           return nullptr;
211       }
212       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "Subscriber successful");
213       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS));
214       ret = OH_Sensor_Unsubscribe(id, g_user); // Unsubscribe from sensor data.
215       if (ret != SENSOR_SUCCESS) {
216           return nullptr;
217       }
218       if (id != nullptr) {
219           OH_Sensor_DestroySubscriptionId(id); // Destroy the Sensor_SubscriptionId instance and reclaim the memory.
220       }
221       if (attr != nullptr) {
222           OH_Sensor_DestroySubscriptionAttribute(attr); // Destroy the Sensor_SubscriptionAttribute instance and reclaim the memory.
223       }
224       if (g_user != nullptr) {
225           OH_Sensor_DestroySubscriber(g_user); // Destroy the Sensor_Subscriber instance and reclaim the memory.
226           g_user = nullptr;
227       }
228   }
229   ```
230
2319. Add related APIs to the **Init** function.
232
233   ```c
234   static napi_value Init(napi_env env, napi_value exports)
235      {
236          napi_property_descriptor desc[] = {
237              { "getSensorInfos", nullptr, GetSensorInfos, nullptr, nullptr, nullptr, napi_default, nullptr },
238              { "subscriber", nullptr, Subscriber, nullptr, nullptr, nullptr, napi_default, nullptr }
239          };
240          napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
241          return exports;
242      }
243      EXTERN_C_END
244   ```
245
24610. Introduce the NAPI APIs to the **index.d.ts** file in **types/libentry**.
247
248    ```c
249     export const getSensorInfos: () => number;
250     export const subscriber: () => number;
251    ```
252
25311. Delete deprecated functions from the **Index.ets** file.
254
255    ```js
256    .onClick(() => {
257        hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3));
258    })
259    ```
260