1e41f4b71Sopenharmony_ci# Sensor Development (C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## When to Use
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciWith 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.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ciFor details about the APIs, see [Sensor API Reference](../../reference/apis-sensor-service-kit/_sensor.md).
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci## Function Description
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci| Name                                                        | Description                                                        |
13e41f4b71Sopenharmony_ci| ------------------------------------------------------------ | ------------------------------------------------------------ |
14e41f4b71Sopenharmony_ci| OH_Sensor_GetInfos(Sensor_Info **infos, uint32_t *count)     | Obtains information about all sensors on the device.                                |
15e41f4b71Sopenharmony_ci| 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.|
16e41f4b71Sopenharmony_ci| 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.|
17e41f4b71Sopenharmony_ci| 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).|
18e41f4b71Sopenharmony_ci| 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).|
19e41f4b71Sopenharmony_ci| OH_SensorInfo_GetName(Sensor_Info *sensor, char *sensorName, uint32_t *length) | Obtains the sensor name.                                            |
20e41f4b71Sopenharmony_ci| OH_SensorInfo_GetVendorName(Sensor_Info* sensor, char *vendorName, uint32_t *length) | Obtains the sensor's vendor name.                                      |
21e41f4b71Sopenharmony_ci| OH_SensorInfo_GetType(Sensor_Info* sensor, Sensor_Type *sensorType) | Obtains the sensor type.                                            |
22e41f4b71Sopenharmony_ci| OH_SensorInfo_GetResolution(Sensor_Info* sensor, float *resolution) | Obtains the sensor resolution.                                          |
23e41f4b71Sopenharmony_ci| OH_SensorInfo_GetMinSamplingInterval(Sensor_Info* sensor, int64_t *minSamplingInterval) | Obtains the minimum data reporting interval of a sensor.                              |
24e41f4b71Sopenharmony_ci| OH_SensorInfo_GetMaxSamplingInterval(Sensor_Info* sensor, int64_t *maxSamplingInterval) | Obtains the maximum data reporting interval of a sensor.                          |
25e41f4b71Sopenharmony_ci| OH_SensorEvent_GetType(Sensor_Event* sensorEvent, Sensor_Type *sensorType) | Obtains the sensor type.                                            |
26e41f4b71Sopenharmony_ci| OH_SensorEvent_GetTimestamp(Sensor_Event* sensorEvent, int64_t *timestamp) | Obtains the timestamp of sensor data.                                    |
27e41f4b71Sopenharmony_ci| OH_SensorEvent_GetAccuracy(Sensor_Event* sensorEvent, Sensor_Accuracy *accuracy) | Obtains the accuracy of sensor data.                                      |
28e41f4b71Sopenharmony_ci| 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.|
29e41f4b71Sopenharmony_ci| OH_Sensor_CreateSubscriptionId(void)                         | Creates a **Sensor_SubscriptionId** instance.                        |
30e41f4b71Sopenharmony_ci| OH_Sensor_DestroySubscriptionId(Sensor_SubscriptionId *id)   | Destroys a **Sensor_SubscriptionId** instance and reclaims memory.                  |
31e41f4b71Sopenharmony_ci| OH_SensorSubscriptionId_GetType(Sensor_SubscriptionId *id, Sensor_Type *sensorType) | Obtains the sensor type.                                            |
32e41f4b71Sopenharmony_ci| OH_SensorSubscriptionId_SetType(Sensor_SubscriptionId* id, const Sensor_Type sensorType) | Sets the sensor type.                                            |
33e41f4b71Sopenharmony_ci| OH_Sensor_CreateSubscriptionAttribute(void)                  | Creates a **Sensor_SubscriptionAttribute** instance.                      |
34e41f4b71Sopenharmony_ci| OH_Sensor_DestroySubscriptionAttribute(Sensor_SubscriptionAttribute *attribute) | Destroys a **Sensor_SubscriptionAttribute** instance and reclaims memory.            |
35e41f4b71Sopenharmony_ci| OH_SensorSubscriptionAttribute_SetSamplingInterval(Sensor_SubscriptionAttribute* attribute, const int64_t samplingInterval) | Sets the interval for reporting sensor data.                                    |
36e41f4b71Sopenharmony_ci| OH_SensorSubscriptionAttribute_GetSamplingInterval(Sensor_SubscriptionAttribute* attribute, int64_t *samplingInterval) | Obtains the interval for reporting sensor data.                                    |
37e41f4b71Sopenharmony_ci| OH_Sensor_CreateSubscriber(void)                             | Creates a **Sensor_Subscriber** instance.                             |
38e41f4b71Sopenharmony_ci| OH_Sensor_DestroySubscriber(Sensor_Subscriber *subscriber)   | Destroys a **Sensor_Subscriber** instance and reclaims memory.                       |
39e41f4b71Sopenharmony_ci| OH_SensorSubscriber_SetCallback(Sensor_Subscriber* subscriber, const Sensor_EventCallback callback) | Sets a callback function to report sensor data.                          |
40e41f4b71Sopenharmony_ci| OH_SensorSubscriber_GetCallback(Sensor_Subscriber* subscriber, Sensor_EventCallback *callback) | Obtains the callback function used to report sensor data.                          |
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci## How to Develop
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ciThe following uses the acceleration sensor as an example to describe the development procedure.
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci1. Create a native C++ project.
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci   ![Create a project](figures/004.png)
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci2. Check whether the corresponding permission has been configured. For details, see [Declaring Permissions](../../security/AccessToken/declare-permissions.md).
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci   ```json
54e41f4b71Sopenharmony_ci   "requestPermissions": [
55e41f4b71Sopenharmony_ci         {
56e41f4b71Sopenharmony_ci           "name": "ohos.permission.ACCELEROMETER",
57e41f4b71Sopenharmony_ci         },
58e41f4b71Sopenharmony_ci       ]
59e41f4b71Sopenharmony_ci   ```
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci3. Add the dynamic dependency libraries into the **CMakeLists.txt** file.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci   ```c
64e41f4b71Sopenharmony_ci   target_link_libraries(entry PUBLIC libace_napi.z.so)
65e41f4b71Sopenharmony_ci   target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
66e41f4b71Sopenharmony_ci   target_link_libraries(entry PUBLIC libohsensor.so)
67e41f4b71Sopenharmony_ci   ```
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci4. Import the module.
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci   ```c
72e41f4b71Sopenharmony_ci   #include "sensors/oh_sensor.h"
73e41f4b71Sopenharmony_ci   #include "napi/native_api.h"
74e41f4b71Sopenharmony_ci   #include "hilog/log.h"
75e41f4b71Sopenharmony_ci   #include <thread>
76e41f4b71Sopenharmony_ci   ```
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci5. Define constants.
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci   ```c
81e41f4b71Sopenharmony_ci   const int GLOBAL_RESMGR = 0xFF00;
82e41f4b71Sopenharmony_ci   const char *TAG = "[Sensor]";
83e41f4b71Sopenharmony_ci   constexpr Sensor_Type SENSOR_ID { SENSOR_TYPE_ACCELEROMETER };
84e41f4b71Sopenharmony_ci   constexpr uint32_t SENSOR_NAME_LENGTH_MAX = 64;
85e41f4b71Sopenharmony_ci   constexpr int64_t SENSOR_SAMPLE_PERIOD = 200000000;
86e41f4b71Sopenharmony_ci   constexpr int32_t SLEEP_TIME_MS = 1000;
87e41f4b71Sopenharmony_ci   constexpr int64_t INVALID_VALUE = -1;
88e41f4b71Sopenharmony_ci   constexpr float INVALID_RESOLUTION = -1.0F;
89e41f4b71Sopenharmony_ci   Sensor_Subscriber *g_user = nullptr;
90e41f4b71Sopenharmony_ci   ```
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci6. Define a callback function to receive sensor data.
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci   ```c
95e41f4b71Sopenharmony_ci   void SensorDataCallbackImpl(Sensor_Event *event) {
96e41f4b71Sopenharmony_ci       if (event == nullptr) {
97e41f4b71Sopenharmony_ci           OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "event is null");
98e41f4b71Sopenharmony_ci           return;
99e41f4b71Sopenharmony_ci       }
100e41f4b71Sopenharmony_ci       int64_t timestamp = INVALID_VALUE;
101e41f4b71Sopenharmony_ci       int32_t ret = OH_SensorEvent_GetTimestamp(event, &timestamp); // Obtain the timestamp of sensor data.
102e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
103e41f4b71Sopenharmony_ci           return;
104e41f4b71Sopenharmony_ci       }
105e41f4b71Sopenharmony_ci       Sensor_Type sensorType;
106e41f4b71Sopenharmony_ci       ret = OH_SensorEvent_GetType(event, &sensorType); // Obtain the sensor type.
107e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
108e41f4b71Sopenharmony_ci           return;
109e41f4b71Sopenharmony_ci       }
110e41f4b71Sopenharmony_ci       Sensor_Accuracy accuracy = SENSOR_ACCURACY_UNRELIABLE;
111e41f4b71Sopenharmony_ci       ret = OH_SensorEvent_GetAccuracy(event, &accuracy); // Obtain the accuracy of sensor data.
112e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
113e41f4b71Sopenharmony_ci           return;
114e41f4b71Sopenharmony_ci       }
115e41f4b71Sopenharmony_ci       float *data = nullptr;
116e41f4b71Sopenharmony_ci       uint32_t length = 0;
117e41f4b71Sopenharmony_ci       ret = OH_SensorEvent_GetData(event, &data, &length); // Obtain sensor data.
118e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
119e41f4b71Sopenharmony_ci           return;
120e41f4b71Sopenharmony_ci       }
121e41f4b71Sopenharmony_ci       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "sensorType:%{public}d, dataLen:%{public}d, accuracy:%{public}d", sensorType, length, accuracy);
122e41f4b71Sopenharmony_ci       for (uint32_t i = 0; i < length; ++i) {
123e41f4b71Sopenharmony_ci           OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "data[%{public}d]:%{public}f", i, data[i]);
124e41f4b71Sopenharmony_ci       }
125e41f4b71Sopenharmony_ci   }
126e41f4b71Sopenharmony_ci   ```
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci7. Obtain information about all sensors on the device. 
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ci   ```c
131e41f4b71Sopenharmony_ci   static napi_value GetSensorInfos(napi_env env, napi_callback_info info)
132e41f4b71Sopenharmony_ci   {
133e41f4b71Sopenharmony_ci       uint32_t count = 0;
134e41f4b71Sopenharmony_ci       int32_t ret = OH_Sensor_GetInfos(nullptr, &count); // Obtain the number of all sensors on the device.
135e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
136e41f4b71Sopenharmony_ci           return nullptr;
137e41f4b71Sopenharmony_ci       }
138e41f4b71Sopenharmony_ci       Sensor_Info **sensors = OH_Sensor_CreateInfos(count); // Create an array of instances with the given number.
139e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
140e41f4b71Sopenharmony_ci           return nullptr;
141e41f4b71Sopenharmony_ci       }        
142e41f4b71Sopenharmony_ci       ret = OH_Sensor_GetInfos(sensors, &count); // Obtain information about all sensors on the device.
143e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
144e41f4b71Sopenharmony_ci           return nullptr;
145e41f4b71Sopenharmony_ci       }
146e41f4b71Sopenharmony_ci       for (uint32_t i = 0; i < count; ++i) {
147e41f4b71Sopenharmony_ci           char sensorName[SENSOR_NAME_LENGTH_MAX] = {};
148e41f4b71Sopenharmony_ci           uint32_t length = SENSOR_NAME_LENGTH_MAX;
149e41f4b71Sopenharmony_ci           ret = OH_SensorInfo_GetName(sensors[i], sensorName, &length); // Obtain the sensor name.
150e41f4b71Sopenharmony_ci           if (ret != SENSOR_SUCCESS) {
151e41f4b71Sopenharmony_ci               return nullptr;
152e41f4b71Sopenharmony_ci           }
153e41f4b71Sopenharmony_ci           char vendorName[SENSOR_NAME_LENGTH_MAX] = {};
154e41f4b71Sopenharmony_ci           length = SENSOR_NAME_LENGTH_MAX;
155e41f4b71Sopenharmony_ci           ret = OH_SensorInfo_GetVendorName(sensors[i], vendorName, &length); // Obtain the manufacturer name of the sensor.
156e41f4b71Sopenharmony_ci           if (ret != SENSOR_SUCCESS) {
157e41f4b71Sopenharmony_ci               return nullptr;
158e41f4b71Sopenharmony_ci           }
159e41f4b71Sopenharmony_ci           Sensor_Type sensorType;
160e41f4b71Sopenharmony_ci           ret = OH_SensorInfo_GetType(sensors[i], &sensorType); // Obtain the sensor type.
161e41f4b71Sopenharmony_ci           if (ret != SENSOR_SUCCESS) {
162e41f4b71Sopenharmony_ci               return nullptr;
163e41f4b71Sopenharmony_ci           }
164e41f4b71Sopenharmony_ci           float resolution = INVALID_RESOLUTION;
165e41f4b71Sopenharmony_ci           ret = OH_SensorInfo_GetResolution(sensors[i], &resolution); // Obtain the sensor resolution.
166e41f4b71Sopenharmony_ci           if (ret != SENSOR_SUCCESS) {
167e41f4b71Sopenharmony_ci               return nullptr;
168e41f4b71Sopenharmony_ci           }
169e41f4b71Sopenharmony_ci           int64_t minSamplePeriod = INVALID_VALUE;
170e41f4b71Sopenharmony_ci           ret = OH_SensorInfo_GetMinSamplingInterval(sensors[i], &minSamplePeriod); // Obtain the minimum data reporting interval of a sensor.
171e41f4b71Sopenharmony_ci           if (ret != SENSOR_SUCCESS) {
172e41f4b71Sopenharmony_ci               return nullptr;
173e41f4b71Sopenharmony_ci           }
174e41f4b71Sopenharmony_ci           int64_t maxSamplePeriod = INVALID_VALUE;
175e41f4b71Sopenharmony_ci           ret = OH_SensorInfo_GetMaxSamplingInterval(sensors[i], &maxSamplePeriod); // Obtain the maximum data reporting interval of a sensor.
176e41f4b71Sopenharmony_ci           if (ret != SENSOR_SUCCESS) {
177e41f4b71Sopenharmony_ci               return nullptr;
178e41f4b71Sopenharmony_ci           }
179e41f4b71Sopenharmony_ci       }
180e41f4b71Sopenharmony_ci       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "GetSensorInfos sucessful");
181e41f4b71Sopenharmony_ci       ret = OH_Sensor_DestroyInfos(sensors, count); // Destroy an array of instances and reclaim the memory.
182e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
183e41f4b71Sopenharmony_ci           return nullptr;
184e41f4b71Sopenharmony_ci       }
185e41f4b71Sopenharmony_ci   }
186e41f4b71Sopenharmony_ci   ```
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci8. Subscribe to and unsubscribe from sensor data.
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci   ```c
191e41f4b71Sopenharmony_ci   static napi_value Subscriber(napi_env env, napi_callback_info info)
192e41f4b71Sopenharmony_ci   {
193e41f4b71Sopenharmony_ci       g_user = OH_Sensor_CreateSubscriber();                                         // Create a Sensor_Subscriber instance.
194e41f4b71Sopenharmony_ci       int32_t ret = OH_SensorSubscriber_SetCallback(g_user, SensorDataCallbackImpl); // Set a callback function to report sensor data.
195e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
196e41f4b71Sopenharmony_ci           return nullptr;
197e41f4b71Sopenharmony_ci       }
198e41f4b71Sopenharmony_ci   
199e41f4b71Sopenharmony_ci       Sensor_SubscriptionId *id = OH_Sensor_CreateSubscriptionId(); // Create a Sensor_SubscriptionId instance.
200e41f4b71Sopenharmony_ci       ret = OH_SensorSubscriptionId_SetType(id, SENSOR_ID); // Set the sensor type.
201e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
202e41f4b71Sopenharmony_ci           return nullptr;
203e41f4b71Sopenharmony_ci       }
204e41f4b71Sopenharmony_ci   
205e41f4b71Sopenharmony_ci       Sensor_SubscriptionAttribute *attr = OH_Sensor_CreateSubscriptionAttribute(); // Create a Sensor_SubscriptionAttribute instance.
206e41f4b71Sopenharmony_ci       ret = OH_SensorSubscriptionAttribute_SetSamplingInterval(attr, SENSOR_SAMPLE_PERIOD); // Set the interval for reporting sensor data.
207e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
208e41f4b71Sopenharmony_ci           return nullptr;
209e41f4b71Sopenharmony_ci       }
210e41f4b71Sopenharmony_ci   
211e41f4b71Sopenharmony_ci       ret = OH_Sensor_Subscribe(id, attr, g_user); // Subscribe to sensor data.
212e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
213e41f4b71Sopenharmony_ci           return nullptr;
214e41f4b71Sopenharmony_ci       }
215e41f4b71Sopenharmony_ci       OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "Subscriber successful");
216e41f4b71Sopenharmony_ci       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS));
217e41f4b71Sopenharmony_ci       ret = OH_Sensor_Unsubscribe(id, g_user); // Unsubscribe from sensor data.
218e41f4b71Sopenharmony_ci       if (ret != SENSOR_SUCCESS) {
219e41f4b71Sopenharmony_ci           return nullptr;
220e41f4b71Sopenharmony_ci       }
221e41f4b71Sopenharmony_ci       if (id != nullptr) {
222e41f4b71Sopenharmony_ci           OH_Sensor_DestroySubscriptionId(id); // Destroy the Sensor_SubscriptionId instance and reclaim the memory.
223e41f4b71Sopenharmony_ci       }
224e41f4b71Sopenharmony_ci       if (attr != nullptr) {
225e41f4b71Sopenharmony_ci           OH_Sensor_DestroySubscriptionAttribute(attr); // Destroy the Sensor_SubscriptionAttribute instance and reclaim the memory.
226e41f4b71Sopenharmony_ci       }
227e41f4b71Sopenharmony_ci       if (g_user != nullptr) {
228e41f4b71Sopenharmony_ci           OH_Sensor_DestroySubscriber(g_user); // Destroy the Sensor_Subscriber instance and reclaim the memory.
229e41f4b71Sopenharmony_ci           g_user = nullptr;
230e41f4b71Sopenharmony_ci       }
231e41f4b71Sopenharmony_ci   }
232e41f4b71Sopenharmony_ci   ```
233e41f4b71Sopenharmony_ci   
234e41f4b71Sopenharmony_ci9. Introduce the NAPI APIs to the **index.d.ts** file in **types/libentry**.
235e41f4b71Sopenharmony_ci
236e41f4b71Sopenharmony_ci   ```c
237e41f4b71Sopenharmony_ci   export const getSensorInfos: () => number;
238e41f4b71Sopenharmony_ci   export const subscriber: () => number;
239e41f4b71Sopenharmony_ci   ```
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci10. Write JavaScript test cases to test the APIs.
242