OpenHarmony Native组件开发 用户指南
本文档介绍 HiDiTing SDK 中 OpenHarmony Native 组件的开发方法。内容覆盖 Location、Sensor、Camera 和 HTTP 四类组件:说明组件职责、关键数据结构、场景开发流程、现有 SDK 代码走读以及如何将这些能力集成到自己的 Native 应用中。
各组件的公开接口以 SDK 头文件为准;本文档在具体场景中给出对应头文件和可运行参考代码的位置,避免重复维护接口参数和返回值说明。
OpenHarmony Native组件背景知识
组件职责
OpenHarmony Native 组件向应用提供 C 或 C++ 形式的系统服务能力。应用只调用公开接口和实现回调,不直接访问 GNSS、传感器或相机硬件;底层框架将请求转发到服务和 HDI/HAL,并将异步数据通过回调返回给应用。

下表给出本指南涉及组件的接口入口、参考实现和典型用途。接口名称可直接跳转到 SDK 中对应的公开声明;参考实现用于理解调用顺序,不建议应用直接依赖内部实现。
| 组件 | Native 接口与用途 | SDK 参考实现 |
|---|---|---|
| Location | Locator 提供位置服务使能、定位请求、卫星状态与 NMEA 订阅。 | location_sample.cpp |
| Sensor | GetAllSensors()、订阅、启停、批处理和上报模式控制。 | sensor_sample.c |
| Camera | CameraKit、Camera、CameraConfig 和 FrameConfig 提供预览、循环采集和单帧拍照能力。 | camera_test.cpp |
| HTTP | HttpClient 提供同步 GET/POST/PUT/DELETE,以及可分步执行的连接、发送和接收流程。 | ohosfwk_at_netstack_dfx.cpp |
组件选择
| 业务需求 | 推荐组件 | 关键输出 |
|---|---|---|
| 获取经纬度、卫星状态或 NMEA 报文 | Location | Location、SatelliteStatus、NMEA 字符串回调。 |
| 获取加速度、陀螺仪、气压、心率或佩戴状态 | Sensor | SensorEvent 及其 data 缓冲区。 |
| 实现预览、连续帧处理或拍照 | Camera | Surface 中的帧数据、相机与帧状态回调。 |
| 访问 REST 服务、上传数据或下载响应内容 | HTTP | 状态码、响应头和响应体缓冲区。 |
组件与编译配置
当前 3322 配置中已经纳入 location_sample、sensor_sample、camera_sample 和 netstack_http 等组件。相关组件列表可在 /src/build/config/target_config/common_config.py 与 /src/build/config/target_config/3322/config.py 中查看。
说明:本文示例命令以一站式 CLI 为主。实际开发可从以下三种环境中选择,推荐使用一站式 CLI。
| 开发环境 | 适用场景 | 使用指南 |
|---|---|---|
| 一站式 CLI(推荐) | 快速完成目标选择、构建、烧录和串口监视 | 一站式 CLI 开发环境使用指南 |
| HiSpark Studio for VS Code | 图形化编辑、编译、烧录和调试 | HiSpark Studio for VS Code 开发环境使用指南 |
| WSL 与 Docker | 在 Windows 上使用一致的 Linux 容器构建环境 | WSL 与 Docker 环境使用指南 |
准备工作:按 一站式 CLI 开发环境使用指南 准备环境、构建和烧录。涉及 GNSS、传感器或相机时,还应确认开发板已具备相应硬件或使用 SDK 提供的模拟实现。
快速跑通定位 Demo
定位组件背景知识
Location 组件目前以 GNSS 定位为核心能力。应用通过 Locator 单例使能位置服务、注册回调并发起定位请求;框架负责管理请求和定位状态,GNSS HDI 负责对接真实芯片或模拟数据源。
图 1 定位子系统架构图

定位子系统包含以下层次:
| 层次 | 职责 |
|---|---|
| Interface | 提供 Locator、定位结果和 GNSS/NMEA 回调等 C++ 接口。 |
| Framework | 实现公开接口,将应用请求转发到 Locator 服务。 |
| Service | 管理定位请求、结果上报、定位能力和状态。 |
| GNSS HDI | 屏蔽硬件差异,对接 GNSS 芯片或模拟定位数据。 |
功能与关键数据
| 类或数据结构 | 作用 |
|---|---|
| Locator | 获取定位服务实例、使能服务、启动/停止定位和订阅 GNSS/NMEA。 |
| ILocatorCallback | 接收位置结果、定位状态和错误码。 |
| IGnssStatusCallback | 接收卫星数量、方位角、仰角和载噪比等状态。 |
| INmeaMessageCallback | 接收 GNSS NMEA 标准报文。 |
| Location | 保存经纬度、高度、速度和方向等定位结果。 |
| RequestConfig | 配置定位场景、优先级和时间间隔。 |
RequestConfig 的优先级应按业务选择:PRIORITY_ACCURACY 优先定位精度,PRIORITY_LOW_POWER 适合低功耗周期定位,PRIORITY_FAST_FIRST_FIX 用于优先获得首次定位结果。完整枚举定义见 /src/ohos/base/location/location_lite/interfaces/kits/include/constant_definition.h。
定位开发流程

核心接口
| 操作 | 接口 | 说明 |
|---|---|---|
| 获取实例、查询/使能服务 | Locator::GetInstance、IsLocationEnabled、EnableAbility | 先确认服务状态,再执行使能或去使能。 |
| 启动/停止定位 | StartLocating、StopLocating | 启动时同时传入请求配置和位置回调;停止时传入同一回调对象。 |
| 卫星/NMEA 订阅 | RegisterGnssStatusCallback、RegisterNmeaMessageCallback | 应在启动定位前注册,退出时成对注销。 |
| 查询坐标系 | QuerySupportCoordinateSystemType | 根据返回列表选择应用使用的坐标系。 |
关键配置
HiDiTingV100 默认提供 GNSS Emulator,在未接入实际 GNSS 芯片时读取 /user/gnss_nmea.log 中的 NMEA 数据并按固定周期上报。数据文件路径由 /src/ohos/drivers/peripheral/location/gnss/gnss_emulator/source/gnss_emulator_vendor_impl.cpp 的 g_gnssNmeaFile 配置。
接入实际 GNSS 芯片时,应完成芯片驱动和 GNSS HDI 适配;GNSS 组件选择和构建入口位于 /src/ohos/drivers/peripheral/location/CMakeLists.txt。使用辅助定位数据时,需要先确保板端时间有效,再将解析后的数据放入业务所需目录。
核心代码与走读
以下代码展示最小定位请求的关键调用顺序:
using namespace OHOS::Location;
Locator &locator = Locator::GetInstance();
bool enabled = false;
if (locator.IsLocationEnabled(enabled) == ERRCODE_SUCCESS && !enabled) {
(void)locator.EnableAbility(true);
}
RequestConfig requestConfig;
requestConfig.SetPriority(PRIORITY_ACCURACY);
(void)locator.RegisterGnssStatusCallback(&gnssStatusCallback);
(void)locator.RegisterNmeaMessageCallback(&nmeaMessageCallback);
(void)locator.StartLocating(&requestConfig, &locationCallback);
结束定位时,按下面顺序释放:
(void)locator.StopLocating(&locationCallback);
(void)locator.UnregisterNmeaMessageCallback(&nmeaMessageCallback);
(void)locator.UnregisterGnssStatusCallback(&gnssStatusCallback);
SDK 参考代码与走读:/src/ohos/base/location/location_lite/sample/location_sample.cpp 中:
LocationEnableLocating()获取Locator单例,查询服务状态后调用EnableAbility(true)。LocationStartLocating()先注册卫星和 NMEA 回调,再以PRIORITY_ACCURACY构造RequestConfig并调用StartLocating()。LocatorCallback::OnLocationReport()读取纬度、经度、高度、速度和方向;OnErrorReport()与OnLocatingStatusChange()用于维护业务状态。LocationStopLocating()先注销附加回调,再停止位置请求,避免停止后继续处理无效数据。
预期结果与调试
定位服务使能后,OnLocationReport() 持续输出位置数据;注册卫星状态和 NMEA 回调后,可分别看到卫星信息和 NMEA 报文。使用模拟定位时,首先检查 /user/gnss_nmea.log 是否存在且内容符合 NMEA 格式;使用真实芯片时,优先检查 HDI 初始化、串口/I2C 连接和芯片定位状态。
快速跑通传感器 Demo
传感器组件背景知识
Sensor 组件为轻量设备提供统一的传感器查询、订阅、批处理、上报模式和启停能力。应用通过 SensorUser 注册回调,服务层在收到硬件或虚拟传感器数据时以 SensorEvent 形式上报。
图 2 传感器子系统架构图

| 层次 | 职责 |
|---|---|
| Interface | 提供传感器列表查询、订阅、启停、模式和批处理配置接口。 |
| Framework | 向上分发传感器数据,向下调用传感器服务。 |
| Service | 管理订阅用户、数据上报和传感器状态。 |
| Sensor HDI | 对接物理传感器或虚拟传感器实现,屏蔽硬件差异。 |
关键数据与功能表
| 数据结构或类型 | 作用 |
|---|---|
| SensorInfo | 描述传感器名称、厂商、类型、量程、精度和功耗。 |
| SensorEvent | 上报传感器类型、时间戳、模式、数据指针和数据长度。 |
| SensorUser | 保存订阅者名称、数据回调和用户数据。 |
| SensorTypeId | 标识物理或虚拟传感器类型。 |
| SensorMode | 默认、实时、按变化、单次和 FIFO 上报模式。 |
SDK 示例覆盖的传感器如下表所示。实际可用列表以 GetAllSensors() 返回的结果为准。
| 示例名称 | 类型标识 | 典型数据 |
|---|---|---|
| 加速度计 | SENSOR_TYPE_ID_ACCELEROMETER |
AccelData 的 X/Y/Z 轴数据。 |
| 气压计 | SENSOR_TYPE_ID_BAROMETER |
PressureData 的气压、温度和有效标识。 |
| 陀螺仪 | SENSOR_TYPE_ID_GYROSCOPE |
GyroData 的 X/Y/Z 轴数据。 |
| 心率 | SENSOR_TYPE_ID_HEART_RATE |
单个心率值。 |
| 佩戴检测 | SENSOR_TYPE_ID_WEAR_DETECTION |
佩戴状态。 |
| 计步器 | SENSOR_TYPE_ID_PEDOMETER |
步数或计步状态。 |
| 虚拟加速度算法 | SENSOR_TYPE_ID_VSENSOR_ACCELEROMETER_ALG_SIMU |
算法处理后的虚拟传感器数据。 |
传感器开发流程

核心接口
| 操作 | 接口 | 说明 |
|---|---|---|
| 查询支持的传感器 | GetAllSensors | 返回 SensorInfo 数组和数量,先确认设备能力。 |
| 订阅/取消订阅 | SubscribeSensor、UnsubscribeSensor | 同一个 SensorUser 对象应贯穿订阅和取消订阅。 |
| 使能/去使能 | ActivateSensor、DeactivateSensor | 使能后才会向订阅用户上报数据。 |
| 设置批处理 | SetBatch | 设置采样间隔和上报间隔。 |
| 设置模式 | SetMode | 使用 SensorMode 选择上报策略。 |
核心代码与走读
回调中必须先校验 data、dataLen 和 sensorTypeId,再将数据转换为该类型对应的结构:
static void RecordAccelSensorCallback(SensorEvent *event)
{
if (event == NULL || event->data == NULL ||
event->sensorTypeId != SENSOR_TYPE_ID_ACCELEROMETER ||
event->dataLen % sizeof(AccelData) != 0) {
return;
}
uint32_t count = event->dataLen / sizeof(AccelData);
AccelData *data = (AccelData *)event->data;
for (uint32_t i = 0; i < count; i++) {
/* 使用 data[i].axisX、axisY、axisZ。 */
}
}
static SensorUser g_accelUser = {
.name = "native_accel",
.callback = RecordAccelSensorCallback,
};
(void)SubscribeSensor(SENSOR_TYPE_ID_ACCELEROMETER, &g_accelUser);
(void)ActivateSensor(SENSOR_TYPE_ID_ACCELEROMETER, &g_accelUser);
SDK 参考代码与走读:/src/ohos/base/sensors/sensor_lite/sample/sensor_sample.c 中:
SensorGetAllSensors()通过GetAllSensors()缓存设备支持的列表。SensorSubscribe()在调用SubscribeSensor()前检查本地订阅状态,避免重复订阅。SensorActivate()仅在未使能时调用ActivateSensor();SensorSetBatch()和SensorSetMode()在同一SensorUser上配置采样与上报行为。RecordAccelSensorCallback()、RecordBarSensorCallback()和RecordCyroSensorCallback()均先检查长度和传感器类型,再按对应数据结构解析。SensorDeactivate()在去使能前处理已订阅状态,应用退出时应确保订阅和使能状态均已清理。
传感器驱动适配与预期结果
当前 SDK 可使用模拟传感器实现;对接新硬件传感器时,应在 /src/ohos/drivers/peripheral/sensor/hal_lite/sensors 下实现对应 HDI 插件,并在 /src/ohos/drivers/peripheral/sensor/CMakeLists.txt 中纳入构建。
使能并订阅有效传感器后,数据回调应持续收到与类型匹配的 SensorEvent。若无数据,依次检查 GetAllSensors() 是否包含该类型、是否已订阅并使能、采样间隔是否合理,以及传感器 HDI 是否已初始化。
快速跑通相机 Demo
相机组件背景知识
Camera 组件通过 CameraLite 框架提供相机枚举、能力查询、相机创建、预览、循环采集和单帧拍照能力。应用创建 Camera 后,在 CameraStateCallback::OnCreated() 回调内完成相机配置;每种业务将 Surface 加入 FrameConfig,再触发预览、录像或拍照。
图 3 Camera子系统架构图

| 层次 | 职责 |
|---|---|
| Camera 应用 | 创建相机、配置 Surface、处理帧与状态回调。 |
| CameraLite | 提供 Native 相机接口及业务状态管理。 |
| Camera HAL | 屏蔽具体摄像头的初始化、能力和 Buffer 填充差异。 |
| 驱动层 | 提供 GPIO、I2C、ISP 和视频输入等硬件能力。 |
Camera NAPI 与关键数据表
| 类 | 核心接口 | 用途 |
|---|---|---|
| CameraKit | GetInstance、GetCameraIds、GetCameraAbility、CreateCamera |
获取相机框架、枚举相机、查询能力并异步创建相机。 |
| Camera | Configure、TriggerLoopingCapture、StopLoopingCapture、TriggerSingleCapture、Release |
配置设备、启动/停止循环采集、单帧拍照和释放资源。 |
| CameraConfig | CreateCameraConfig、帧状态回调配置 |
为相机设置帧回调和事件处理器。 |
| FrameConfig | 预览/录像/拍照类型、AddSurface、参数设置 |
承载单个采集业务的 Surface 和帧参数。 |
| FrameConfig 类型 | 用途 | 典型 Surface 行为 |
|---|---|---|
FRAME_CONFIG_PREVIEW |
预览 | 将 Surface 配置到 UI 控件树中显示画面。 |
FRAME_CONFIG_RECORD / FRAME_CONFIG_CALLBACK |
循环采集或码流处理 | 通过帧回调获取 Buffer,进行录制、编码或发送。 |
FRAME_CONFIG_CAPTURE |
单帧拍照 | 单次采集完成后从 Surface 获取图像数据。 |
相机开发流程

关键配置与硬件适配
Camera 业务由 diting-community-native-js 目标中的 camera_sample、camera_lite、camera_hal 等组件提供支持,相关配置见 /src/build/config/target_config/3322/config.py。
图 4 watch_type 配置示意

当前 3322 目标的 watch_type 取值位于 /src/build/config/target_config/3322/target_config.py。相机功能应优先确认目标已启用 diting-community-native-js 对应的 Camera 组件,而不是仅依据截图修改配置项。
适配特定摄像头时,重点检查 /src/middleware/services/media/hal/camera_lite 的 GPIO 复位、IO 引脚、I2C 地址、寄存器初始化序列以及 HalCameraGetStreamCap() 上报的分辨率和帧率能力。
核心代码与走读
相机创建和配置应在回调链中完成:
CameraKit *cameraKit = CameraKit::GetInstance();
std::list<std::string> cameraIds = cameraKit->GetCameraIds();
if (!cameraIds.empty()) {
cameraKit->CreateCamera(cameraIds.front(), cameraStateCallback, eventHandler);
}
void DemoCameraStateCallback::OnCreated(Camera &camera)
{
CameraConfig *config = CameraConfig::CreateCameraConfig();
config->SetFrameStateCallback(&frameStateCallback, &eventHandler);
camera.Configure(*config);
camera.TriggerLoopingCapture(previewFrameConfig);
}
SDK 参考代码与走读:/src/ohos/foundation/multimedia/camera_lite/sample/camera_test.cpp 中:
CameraInit()取得CameraKit,读取相机 ID 列表并调用CreateCamera();相机对象只有在OnCreated()后可用。OnCreated()创建CameraConfig、注册帧状态回调、调用Configure(),然后保存Camera指针。SetFrameConfig()和CreateSurface()为预览、录像和拍照创建匹配的 Surface 与帧参数;Surface 为空时不可启动采集。StartPreview()/StopPreview()调用循环采集接口;Capture()调用TriggerSingleCapture()后从 Surface 获取图像数据;业务结束时调用Release()并清理 Surface。
预期结果与调试
预览场景中,Camera 创建与配置成功后 UI Surface 显示画面;拍照场景中,单帧完成后可以从 Surface 获取 Buffer。若 GetCameraIds() 返回空列表,先检查相机 HAL 是否加载、硬件连接与 I2C 通信是否正常;若创建成功但无画面,检查 FrameConfig 类型、Surface 尺寸/格式和 HalCameraGetStreamCap() 返回的能力是否匹配。
快速跑通 HTTP Demo
HTTP组件背景知识
HTTP 组件提供两类使用方式:HttpClientGetRequest 等同步接口适用于一次性 GET、POST、PUT、DELETE 请求;HttpClientConn、HttpClientSend 和 HttpClientRecvResponse 适用于需要控制连接、发送和分块接收的场景。所有接口在调用线程中执行,网络业务不应阻塞 UI 或高优先级任务。
HTTP 请求、数据与错误码表
| 场景 | 接口 | 说明 |
|---|---|---|
| 同步请求 | HttpClientGetRequest、HttpClientHeadRequest、HttpClientPostRequest、HttpClientPutRequest、HttpClientDelete | 以 URL 为输入,调用完成后获得响应。 |
| 分步请求 | HttpClientConn、HttpClientSend、HttpClientRecvResponse、HttpClientClose | 分别建立连接、发送请求、循环接收响应和关闭连接。 |
| 请求扩展 | HttpClientSetCustomHeader、HttpClientGetResponseCode | 设置自定义请求头,获取 HTTP 状态码。 |
HttpClientData 字段 |
作用 |
|---|---|
postBuf / postBufLen / postContentType |
POST/PUT 请求体、长度和内容类型。 |
responseBuf / responseBufLen |
响应体缓冲区及长度;缓冲区由应用准备。 |
headerBuf / headerBufLen |
响应头缓冲区及长度。 |
contentBlockLen / responseContentLen |
本次接收的数据长度和响应体总长度。 |
isMore / isChunked |
指示是否还需要继续接收,以及响应是否采用分块传输。 |
isRedirected / redirectUrl |
指示是否收到重定向及重定向地址。 |
| 结果码 | 含义 |
|---|---|
HTTP_SUCCESS |
成功。 |
HTTP_EAGAIN |
仍有数据需要继续获取。 |
HTTP_ENOBUFS / HTTP_EARG / HTTP_ENOTSUPP |
缓冲区不足、参数错误或功能不支持。 |
HTTP_EDNS / HTTP_ECONN |
DNS 解析或连接失败。 |
HTTP_ESEND / HTTP_ERECV / HTTP_ECLSD |
发送失败、接收失败或连接已关闭。 |
HTTP_EPARSE / HTTP_EPROTO / HTTP_EUNKNOW / HTTP_ETIMEOUT |
URL 解析、协议、未知或超时错误。 |
完整的 HttpClient、HttpClientData 与 HTTPC_RESULT 定义见 /src/ohos/foundation/arkui/ace_engine_lite/frameworks/src/core/modules/netstack/http/include/httpclient.h。
HTTP开发流程

核心代码与走读
以下示例使用分步接口处理可能分块返回的响应:
HttpClient client = {0};
HttpClientData data = {0};
HTTPC_RESULT ret = HTTP_SUCCESS;
char response[2048] = {0};
char header[2048] = {0};
data.responseBuf = response;
data.responseBufLen = sizeof(response);
data.headerBuf = header;
data.headerBufLen = sizeof(header);
client.timeoutMs = 40000;
ret = HttpClientConn(&client, url);
if (ret != HTTP_SUCCESS) {
goto exit;
}
ret = HttpClientSend(&client, url, HTTP_GET, &data);
if (ret != HTTP_SUCCESS) {
goto exit;
}
do {
ret = HttpClientRecvResponse(&client, &data);
/* 本轮数据长度为 data.contentBlockLen,应在下一轮接收前处理或复制。 */
if (ret < HTTP_SUCCESS && ret != HTTP_EAGAIN) {
break;
}
} while (ret == HTTP_EAGAIN || data.isMore);
exit:
HttpClientClose(&client);
return ret;
}
HttpClientRecvResponse() 要求 headerBufLen 与 responseBufLen 均不小于 2048 字节;代码中的两个 2048 字节数组满足该要求。每次接收后,响应体有效长度由 contentBlockLen 给出,不能将整个缓冲区都视为本轮有效数据。
SDK 参考代码与走读:/src/middleware/utils/at/at_ohos_cmd/at/at_ohos_process_cpp/ohosfwk_at_netstack_dfx.cpp 按“配置缓冲区 → HttpClientConn() → HttpClientSend() → 循环 HttpClientRecvResponse() → HttpClientClose()”处理网络诊断请求;/src/application/wearable/service/amap_adapter/amap_os_adapter/amap_net_adapter.c 对连接、发送和接收分别检查错误并在结束路径统一关闭连接。
预期结果与调试
网络连通且 URL 正确时,HttpClientGetResponseCode() 返回服务端状态码,响应头写入 headerBuf,响应体分段写入 responseBuf。若使用 4G CAT1 公网访问,先确认 DNS、网络注册和 IP 获取状态;遇到 HTTP_EAGAIN 时继续接收,遇到负错误码时按错误类别定位 DNS、连接、发送、接收或超时问题。
基于 Native 组件 Demo 开发自己的组件
下面以“定位、传感器和 HTTP 上报”类应用为例说明如何建立自己的 Native 组件应用;相机应用可沿用同样的组件组织和资源释放模式。
- 建立独立组件。 在 /samples/native_samples/ 下创建目录,并参考 /samples/native_samples/adc/CMakeLists.txt 编写
CMakeLists.txt。在 /samples/native_samples/CMakeLists.txt 中通过功能宏和add_subdirectory_if_exist()纳入组件。 - 声明需要的头文件路径。 Location、Sensor、Camera 和 HTTP 分别加入对应公开头文件所在目录。C++ 组件需在
CMakeLists.txt中启用 C++ 编译并使用与 SDK 示例一致的 C++ 标准和编译选项;可参考 /src/ohos/base/location/location_lite/sample/CMakeLists.txt 和 /src/ohos/foundation/multimedia/camera_lite/sample/CMakeLists.txt。 - 先实现异步回调和业务状态。 Location 的三类回调、Sensor 的
RecordSensorCallback、Camera 的状态/帧回调都应在应用对象生命周期内保持有效。使用状态机记录“未初始化、已订阅、已使能、运行中、释放中”,不要只依赖接口的同步返回值。 - 按资源获取的反向顺序释放。 停止定位后注销定位附加回调;传感器先去使能再去订阅;相机停止采集后释放相机和 Surface;HTTP 在所有成功和失败分支中调用
HttpClientClose()。 - 逐模块验证。 先验证 Location/Sensor/Camera/HTTP 的单一功能和回调日志,再将数据处理、UI 显示或网络上报组合到同一应用,避免把硬件适配和业务逻辑问题混在一起排查。
建议每个组件使用独立源文件,例如 native_location.c、native_sensor.c、native_camera.cpp、native_http.c,由应用入口统一初始化和停止。这样可以保持 C/C++ 编译边界清晰,也便于按需裁剪组件。
可编译应用的组件注册链路
在 GitCode 的 native_samples 示例目录中创建应用子目录后,还需要完成“目录注册 → 功能宏 → 目标组件”三步,应用才会参与目标构建。以下链路与现有 Native 组件的注册方式一致。

- 在上述
native_samples目录中为应用建立独立子目录,创建源码和CMakeLists.txt,并为组件指定唯一的COMPONENT_NAME,例如native_ohos_app。 -
在 /samples/native_samples/CMakeLists.txt 中加入功能宏控制,避免默认构建时无条件纳入所有应用:
-
在选用目标的 /src/build/config/target_config/3322/config.py 中增加
CONFIG_ENABLE_NATIVE_OHOS_APP,并在对应的ram_component中加入native_ohos_app。Location、Sensor、Camera 或 HTTP 应用还必须选择已纳入 OpenHarmony 框架组件的目标;当前diting-community-native-js已启用SUPPORT_OHOSFWK,并纳入 Camera 相关组件。 - 按 一站式 CLI 开发环境使用指南 构建和烧录。若只需要一个组件,应先验证该组件在当前目标中已启用,再加入自己的应用组件。
C 组件 CMake 模板
Sensor 和 HTTP 可使用 C 源文件。以下模板以“传感器采集并通过 HTTP 上报”为例;仅保留应用所需头文件目录,组件依赖仍由目标配置中的 OpenHarmony 组件提供。
set(COMPONENT_NAME "native_ohos_app")
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/native_ohos_app.c
${CMAKE_CURRENT_SOURCE_DIR}/native_sensor.c
${CMAKE_CURRENT_SOURCE_DIR}/native_http.c
)
set(PUBLIC_HEADER
${CMAKE_CURRENT_SOURCE_DIR}
)
set(PRIVATE_HEADER
${ROOT_DIR}/ohos/base/sensors/sensor_lite/interfaces/kits/native/include
${ROOT_DIR}/ohos/drivers/peripheral/sensor/interfaces/include
${ROOT_DIR}/ohos/foundation/arkui/ace_engine_lite/frameworks/src/core/modules/netstack/http/include
)
set(PRIVATE_DEFINES)
set(PUBLIC_DEFINES)
set(COMPONENT_CCFLAGS)
set(WHOLE_LINK true)
set(MAIN_COMPONENT false)
build_component()
若应用只使用 HTTP,应删除 Sensor 相关源文件和头文件目录;若只使用 Sensor,应删除 HTTP 相关目录。不要将未使用的组件和驱动一并纳入,避免增加镜像体积和初始化依赖。
C++ 组件 CMake 模板
Location 和 Camera 使用 C++ 接口。Location 应用可先使用以下最小模板;Camera 应用除 C++ 编译选项外,还应以 /src/ohos/foundation/multimedia/camera_lite/sample/CMakeLists.txt 为准补齐 UI、Surface、IPC 和 Camera 框架头文件目录。
enable_language(CXX)
set(COMPONENT_NAME "native_ohos_location_app")
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/native_ohos_location_app.cpp
)
set(PUBLIC_HEADER
${CMAKE_CURRENT_SOURCE_DIR}
)
set(PRIVATE_HEADER
${ROOT_DIR}/ohos/base/location/location_lite/interfaces/kits/include
${ROOT_DIR}/ohos/base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite
)
set(COMPONENT_FLAGS)
list(REMOVE_ITEM COMPONENT_FLAGS -std=gnu99 -std=c99 -std=gnu11 -std=c11)
list(APPEND COMPONENT_FLAGS
-std=c++11
-fno-exceptions
-fno-unwind-tables
-fno-asynchronous-unwind-tables
-nostdlibinc
)
set(COMPONENT_CCFLAGS ${COMPONENT_FLAGS})
set(WHOLE_LINK true)
set(MAIN_COMPONENT false)
build_component()
该模板与 /src/ohos/base/location/location_lite/sample/CMakeLists.txt 的语言和头文件配置保持一致。C++ 应用的回调类、Locator、CameraKit、Camera、FrameConfig 和 Surface 对象不得跨语言边界以 C 结构体方式处理。
四类应用的实现契约
下表说明一个完整应用在初始化、运行和退出阶段必须实现的行为。这些约束补足了仅调用单个接口时容易遗漏的状态和资源管理。
| 组件 | 初始化契约 | 运行契约 | 停止与资源释放 |
|---|---|---|---|
| Location | 获取 Locator,确认并使能服务;创建位置、卫星和 NMEA 回调对象。 |
先注册附加回调,再调用 StartLocating();位置数据在 OnLocationReport() 中处理。 |
StopLocating() 后注销 NMEA 与卫星回调;最后按需去使能服务。 |
| Sensor | 调用 GetAllSensors() 确认可用类型;创建生命周期足够长的 SensorUser。 |
订阅、使能,再按需配置 SetBatch() 和 SetMode();严格按 sensorTypeId/dataLen 解析。 |
先 DeactivateSensor(),再 UnsubscribeSensor();清除本地已订阅/已使能状态。 |
| Camera | 获取 CameraKit 和相机 ID;准备相机状态、帧状态回调与事件处理器。 |
仅在 OnCreated() 后配置 CameraConfig、Surface 和 FrameConfig,再启动采集。 |
停止循环采集,释放 Buffer/Surface,调用 Release();使回调不再访问已释放对象。 |
| HTTP | 准备 HttpClient、HttpClientData、响应头和响应体缓冲区;确认网络已连接。 |
执行同步请求,或采用连接、发送、循环接收的分步流程;按 contentBlockLen 消费本轮数据。 |
所有成功和失败路径均调用 HttpClientClose();应用负责释放自身申请的缓冲区。 |
最小应用骨架
以下骨架适合将各组件拆分为独立初始化与停止函数。它避免在应用入口中混杂业务处理、回调和资源释放逻辑:
static int native_app_start(void)
{
int ret = native_sensor_start();
if (ret != SENSOR_OK) {
return ret;
}
ret = native_http_init();
if (ret != HTTP_SUCCESS) {
native_sensor_stop();
return ret;
}
return 0;
}
static void native_app_stop(void)
{
native_http_deinit();
native_sensor_stop();
}
Location 和 Camera 应用以 C++ 类封装相同的 Start()/Stop() 语义。应用初始化失败时,应只释放已经成功获取的资源;退出路径可以重复调用而不产生二次释放。
AI 开发自检清单
在生成应用代码前,依次确认下列信息。缺少其中任一项时,不应假设硬件存在或接口可用。
| 检查项 | Location | Sensor | Camera | HTTP |
|---|---|---|---|---|
| 目标与组件 | SUPPORT_OHOSFWK、Location 组件 |
sensor_client、sensor_service、sensor_hdi |
camera_lite、camera_hal、目标 UI 配置 |
SUPPORT_LWIP、netstack_http |
| 外部条件 | GNSS 芯片或 NMEA 模拟文件 | 有效 Sensor HDI 或模拟传感器 | 摄像头、GPIO/I2C/ISP 与 HAL 能力 | 网络注册、DNS、服务端 URL/证书 |
| 回调/缓冲区 | 三类回调对象在定位结束前有效 | SensorUser 和事件解析缓冲区有效 |
相机、Surface、帧回调在释放前有效 | 头/体缓冲区长度、分块接收状态有效 |
| 最小验收信号 | 位置/卫星/NMEA 回调日志 | GetAllSensors() 列表和 SensorEvent |
相机 ID、OnCreated()、帧完成或预览画面 |
HTTP 状态码、响应头、响应体 |
Native 组件扩展边界
本指南的 Demo 面向 Native 应用开发。若目标是新增系统级组件或适配新硬件,还需以对应 HDI/HAL 的实现和硬件资料为准:
| 扩展目标 | 需要补充的实现依据 | 主要入口 |
|---|---|---|
| 新 GNSS 芯片 | 芯片通信协议、初始化时序、NMEA/定位数据格式和 GNSS HDI 实现。 | /src/ohos/drivers/peripheral/location/gnss |
| 新传感器或虚拟传感器 | 传感器寄存器说明、量程/精度、采样与上报语义、HDI 插件实现。 | /src/ohos/drivers/peripheral/sensor/hal_lite |
| 新摄像头 | GPIO、I2C 地址、寄存器初始化、ISP 参数、支持的分辨率和帧率。 | /src/middleware/services/media/hal/camera_lite |
| 网络协议扩展 | 服务端协议、身份认证、证书、超时/重试和数据持久化策略。 | /src/ohos/foundation/arkui/ace_engine_lite/frameworks/src/core/modules/netstack/http |
因此,AI 可以依据本文档和 SDK 实现完成 Native 应用;在新增硬件组件时,仍必须取得目标器件的硬件资料和通信协议,再完成 HDI/HAL 适配及板级验证。
注意事项
- Location、Sensor 和 Camera 的结果均为异步回调;回调对象和其依赖缓冲区必须在取消订阅、停止或释放前保持有效。
- GNSS Emulator 仅用于验证定位流程,不代表真实 GNSS 芯片的首次定位时间、卫星数量和精度。
- Sensor 回调必须根据
sensorTypeId和dataLen选择正确的数据结构,禁止把一种传感器的data直接转换为另一种类型。 - Camera 的
CreateCamera()是异步操作,只能在OnCreated()之后调用Configure()和采集接口;Surface、帧格式、分辨率和相机能力必须匹配。 - HTTP 接口会阻塞调用线程。响应可能分段返回,应用需依据
HTTP_EAGAIN和isMore持续接收,并始终关闭连接。 - 业务代码只包含公开头文件,不应直接调用组件内部的 Service、HDI 或 HAL 实现函数。
常见编译错误
| 现象 | 排查方法 |
|---|---|
找不到 locator.h、sensor_agent.h、camera_kit.h 或 httpclient.h |
检查组件 CMakeLists.txt 的 PRIVATE_HEADER 是否加入本文“组件职责”表中对应公开头文件的所在目录。 |
| C++ Location/Camera 代码按 C 编译 | 参考 Location/Camera 示例的 CMakeLists.txt 启用 C++ 编译,并使用 C++ 源文件扩展名。 |
| 链接阶段找不到 Location、Sensor、Camera 或 HTTP 符号 | 确认选择的目标已纳入对应组件;参照 /src/build/config/target_config/common_config.py 与 /src/build/config/target_config/3322/config.py 检查配置。 |
SensorEvent 数据长度或类型不匹配 |
在回调中同时校验 sensorTypeId、data、dataLen 和批次数量;不要假设所有传感器均为单个三轴数据。 |
| Camera 创建失败或没有预览画面 | 检查相机 ID、HAL、I2C/GPIO、FrameConfig 类型、Surface 配置和能力集。 |
HTTP 返回 HTTP_EDNS、HTTP_ECONN 或 HTTP_ETIMEOUT |
检查网络注册、DNS、URL、TLS 证书配置、超时值和响应接收循环。 |