BodyAR 从零开始:开发环境搭建与完整项目配置指南
本文详细介绍了鸿蒙AR项目从开发环境搭建到首个BodyAR应用运行的全流程。主要内容包括: 开发环境准备:硬件要求、DevEco Studio安装及SDK配置 项目创建:工程初始化与目录结构解析 权限系统配置:区分系统授权与用户授权,实现动态权限申请 SDK版本与签名管理:确保与目标设备兼容 文章特别强调了权限模型的关键差异,并提供了完整的权限申请代码示例。每个步骤后都附有常见问题解决方案,帮助开

一、前言
本文聚焦于实战环节——从 DevEco Studio 安装到第一个可运行的 BodyAR 项目,全程手把手指导。
本文将覆盖一个完整鸿蒙 AR 项目的初始化全流程,包括 SDK 配置、权限系统、签名管理和首次运行调试。每个步骤后都附有常见问题的排查方案,遇到任何报错都可以在对应章节找到解决方法。
二、开发环境准备
2.1 硬件要求
| 项目 | 最低要求 | 推荐配置 |
|---|---|---|
| 开发机 OS | macOS 12 / Windows 10 | macOS 14 / Windows 11 |
| 开发机内存 | 8 GB | 16 GB |
| 测试手机 | 麒麟 9000 芯片 | 麒麟 9010/9020 芯片 |
| 手机系统 | HarmonyOS NEXT API 23 | HarmonyOS NEXT API 24 |
| 数据线 | USB-C 支持数据传输 | USB 3.0+ |
2.2 安装 DevEco Studio
前往华为开发者官网下载最新版 DevEco Studio。
安装完成后打开 SDK Manager(Configure → Settings → SDK),确保勾选以下组件:
- HarmonyOS SDK → API Version 23+ (6.1.0)
- SDK Tools → Hvigor、Toolchains
2.3 在手机上安装 AR Engine
AR Engine 是预装在华为手机上的系统应用,但可能未更新到最新版。打开手机上的 AppGallery,搜索"AR Engine",如果显示"更新"则点击更新,如果显示"打开"说明已安装最新版。
如果 AppGallery 中搜索不到,说明该机型不支持 AR Engine。
三、创建项目
3.1 新建工程
DevEco Studio → Create Project → Empty Ability,填写以下配置:
| 配置项 | 值 | 说明 |
|---|---|---|
| Project name | BodyARDemo | 项目名称 |
| Bundle name | com.example.bodyardemo | 应用包名,全局唯一 |
| Module name | entry | 主模块名 |
| Device type | Phone | 目标设备 |
| Compatible SDK | 6.1.0(23) | 最低兼容版本 |
| Language | ArkTS | 声明式 UI |
| Ability template | Empty Ability | 空模板 |
点击 Finish 完成创建。
3.2 项目初始结构

BodyARDemo/
├── AppScope/
│ ├── app.json5 # 应用全局标识
│ └── resources/base/
│ ├── element/string.json # 应用名称
│ └── media/ # 应用图标
├── entry/
│ ├── src/main/
│ │ ├── ets/
│ │ │ ├── entryability/ # UIAbility 入口
│ │ │ └── pages/ # 页面组件
│ │ ├── resources/ # 模块级资源
│ │ └── module.json5 # 模块配置(权限在这里)★
│ ├── build-profile.json5 # 模块构建配置
│ └── oh-package.json5 # 模块依赖
├── build-profile.json5 # 工程级构建配置(SDK版本、签名)★
├── hvigor/ # 构建工具
└── oh-package.json5 # 工程级依赖
关注带 ★ 的两个文件,它们是最核心的配置入口。
四、权限系统配置
4.1 理解鸿蒙的权限模型
鸿蒙将权限分为两大类:
| 类型 | 标识 | 授予方式 | 示例 |
|---|---|---|---|
| 系统授权 (system_grant) | "when":"" |
安装时自动授予 | GYROSCOPE, ACCELEROMETER, INTERNET |
| 用户授权 (user_grant) | "when":"inuse" |
运行时弹窗用户确认 | CAMERA, MICROPHONE, LOCATION |
BodyAR 需要三个权限:1 个 user_grant(CAMERA)+ 2 个 system_grant(GYROSCOPE、ACCELEROMETER)。
4.2 在 module.json5 中声明权限
打开 entry/src/main/module.json5,在 module 对象内、abilities 之前添加:
{
"module": {
"name": "entry",
"type": "entry",
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.GYROSCOPE"
// system_grant 不需要 reason 和 usedScene
},
{
"name": "ohos.permission.ACCELEROMETER"
}
],
"abilities": [
// ...
]
}
}
4.3 权限申请理由文本
在 entry/src/main/resources/base/element/string.json 中添加:
{
"string": [
{
"name": "camera_permission_reason",
"value": "相机权限用于获取实时画面以进行人体骨骼追踪"
}
]
}
4.4 运行时请求相机权限
CAMERA 是受限权限,必须在代码中动态申请。在页面的 onStartTracking 方法中添加:
import { abilityAccessCtrl } from '@kit.AbilityKit';
async function requestCameraPermission(): Promise<boolean> {
const atManager = abilityAccessCtrl.createAtManager();
try {
const context = getContext(this);
const tokenId = context.applicationInfo.accessTokenId;
const grantStatus = await atManager.checkAccessToken(
tokenId, 'ohos.permission.CAMERA'
);
// 首次使用:显示权限弹窗
if (grantStatus !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
const result = await atManager.requestPermissionsFromUser(
context, ['ohos.permission.CAMERA']
);
// authResults[0] === 0 表示用户点击了"允许"
return result.authResults[0] === 0;
}
return true; // 已授权
} catch (e) {
console.error('权限检查失败: ' + JSON.stringify(e));
return false;
}
}
权限申请弹窗的行为:
- 用户点击"允许" →
authResults[0] === 0,返回true - 用户点击"拒绝" →
authResults[0] !== 0,返回false,显示提示引导用户去设置中开启 - 用户连续拒绝两次 → 系统不再弹窗,需要引导用户去系统设置手动开启
五、配置 SDK 版本与签名
5.1 SDK 版本配置
打开工程级 build-profile.json5,确认 SDK 版本与目标手机匹配:
{
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"targetSdkVersion": "6.1.0(23)",
"compatibleSdkVersion": "6.1.0(23)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
}
}
]
}
}
三个 SDK 版本字段的关系:
compatibleSdkVersion ≤ targetSdkVersion ≤ compileSdkVersion
- compatibleSdkVersion:最低支持的 API 版本。低于此版本的设备无法安装应用
- targetSdkVersion:目标 API 版本。应用在该版本的行为下运行
- compileSdkVersion:编译使用的 SDK 版本。默认等于 IDE 自带的 SDK 版本
5.2 签名配置
调试签名用于将应用部署到真机。在 DevEco Studio 中:
- File → Project Structure → Signing Configs
- 勾选 “Automatically generate signature”
- 点击 Apply
系统会自动在 ~/.ohos/config/ 目录下生成调试证书、密钥存储文件和 Profile,并将其路径写入 build-profile.json5 的 signingConfigs 中。
如果提交到 Git,务必把 signingConfigs 清空(设为 []),避免泄露密钥密码:
"signingConfigs": [
// 请通过 DevEco Studio 自动生成,不要硬编码密码提交到仓库
]
六、安装依赖
6.1 核心依赖
BodyAR 依赖两个系统 Kit:
// 不需要在 oh-package.json5 中显式添加,
// 系统 Kit 通过 import 即可使用
import { arEngine, ARView, arViewController } from '@kit.AREngine';
import { Scene, Node } from '@kit.ArkGraphics3D';
注意 @kit.AREngine 是系统能力(SystemCapability.AREngine.Core),不在 npm 仓库中。编译时会产生"not supported on all devices"的警告,这是正常的——AR Engine 只在部分设备上可用。
6.2 创建 AR 目录结构
在 entry/src/main/ets/ 下创建 ar/ 目录,用于存放 AR 相关模块:
ets/
├── ar/
│ ├── BodyTypes.ets # 类型定义 + 骨骼连线配置
│ ├── BodyAREngine.ets # AR 会话封装
│ ├── AngleCalculator.ets # 关节角度计算
│ ├── ActionCounter.ets # 动作计数状态机
│ └── DataExporter.ets # 数据导出
├── entryability/
│ └── EntryAbility.ets
└── pages/
├── Index.ets # 启动页
└── BodyARPage.ets # AR 主页面
七、编写最小可运行 Demo
7.1 AR 引擎封装
创建 BodyAREngine.ets,封装 AR 会话的核心生命周期:
import { arEngine, arViewController } from '@kit.AREngine';
import { Scene, Node } from '@kit.ArkGraphics3D';
import { BusinessError } from '@kit.BasicServicesKit';
export class BodyAREngine {
private viewContext: arViewController.ARViewContext | null = null;
private scene: Scene | null = null;
private callback?: (bodies: arEngine.ARBody[]) => void;
setCallback(cb: (bodies: arEngine.ARBody[]) => void): void {
this.callback = cb;
}
async start(): Promise<arViewController.ARViewContext> {
// 1. 加载 3D 场景(必须)
this.scene = await Scene.load();
// 2. 创建 AR 视图上下文
const vc = new arViewController.ARViewContext();
vc.scene = this.scene;
// 3. 帧回调
const callbackImpl = new ARViewCallbackImpl();
callbackImpl.setCallback((bodies) => {
this.callback?.(bodies);
});
vc.callback = callbackImpl;
// 4. 配置 Body Tracking 模式
vc.config = {
type: arEngine.ARType.BODY,
powerMode: arEngine.ARPowerMode.NORMAL,
focusMode: arEngine.ARFocusMode.AUTO,
maxDetectedBodyNum: 1,
cameraLensFacing: 0 // 0=后置, 1=前置
};
// 5. 启动 AR 会话
await vc.init();
this.viewContext = vc;
return vc;
}
async stop(): Promise<void> {
if (this.viewContext) {
this.viewContext.destroy();
this.viewContext = null;
}
this.scene = null;
}
}
7.2 AR 视图回调实现
class ARViewCallbackImpl extends arViewController.ARViewCallback {
private callback?: (bodies: arEngine.ARBody[]) => void;
setCallback(cb: (bodies: arEngine.ARBody[]) => void): void {
this.callback = cb;
}
onAnchorAdd(ctx: arViewController.ARViewContext,
node: Node, anchor: arEngine.ARAnchor): void {
// Body tracking 不使用锚点,空实现即可
}
onAnchorUpdate(ctx: arViewController.ARViewContext,
node: Node, anchor: arEngine.ARAnchor): void {
// Body tracking 不使用锚点,空实现即可
}
async onFrameUpdate(ctx: arViewController.ARViewContext,
sysBootTs: number): Promise<void> {
if (!ctx.session) return;
try {
const session: arEngine.ARSession = ctx.session;
const frame: arEngine.ARFrame = session.getFrame();
const bodies: arEngine.ARBody[] = frame.acquireBodySkeleton();
this.callback?.(bodies);
await frame.release(); // ★ 必须释放!
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`onFrameUpdate: ${err.code} ${err.message}`);
}
}
}
三个关键注意事项:
ARViewCallback是抽象类,必须实现onAnchorAdd、onAnchorUpdate、onFrameUpdate三个方法onAnchorAdd和onAnchorUpdate在 Body 模式下不会触发,但必须实现(不能是抽象类)- 每帧的
frame.release()是硬性要求——不释放会导致底层缓冲区快速耗尽
7.3 ArkUI 页面
import { arEngine, ARView, arViewController } from '@kit.AREngine';
import { BodyAREngine } from '../ar/BodyAREngine';
@Entry
@Component
struct BodyARPage {
@State arContext: arViewController.ARViewContext | null = null;
@State isTracking: boolean = false;
@State statusText: string = '就绪';
private engine: BodyAREngine = new BodyAREngine();
aboutToAppear(): void {
this.engine.setCallback((bodies: arEngine.ARBody[]) => {
// 在此处理每帧检测到的人体列表
console.info('检测到 ' + bodies.length + ' 人');
});
}
async onStartTracking(): Promise<void> {
try {
this.statusText = '初始化中...';
this.arContext = await this.engine.start();
this.isTracking = true;
this.statusText = '追踪中';
} catch (e) {
this.statusText = '错误: ' + JSON.stringify(e);
}
}
build() {
Column() {
Stack() {
if (this.arContext) {
ARView({ context: this.arContext })
.width('100%').height('100%')
}
}.layoutWeight(1)
Text(this.statusText).padding(8)
Button(this.isTracking ? '停止' : '开始')
.onClick(() => this.isTracking ?
this.engine.stop() : this.onStartTracking())
}
}
}
7.4 注册页面路由
在 main_pages.json 中注册页面:
{
"src": [
"pages/Index",
"pages/BodyARPage"
]
}
7.5 运行与验证
- 用 USB 数据线连接手机 → 开启开发者模式 + USB 调试
- DevEco Studio → Run → Run ‘entry’
- 等待编译部署 → 手机上自动打开应用
- 点击"开始" → 弹窗请求相机权限 → 授予
- 如果看到相机画面 → AR 会话启动成功
八、常见问题排查手册
问题 1:编译报错 “arkts-no-destruct-decls”
原因:ArkTS 不支持 ES6 解构语法。
// 错误
const { x, y } = point;
// 正确
const x = point.x;
const y = point.y;
问题 2:部署报 “SDK version mismatch”
原因:compatibleSdkVersion 与手机系统 API 版本不一致。
解决:检查手机 HarmonyOS 版本对应的 API Level,同步修改 build-profile.json5 中的三个版本号。API 23 对应 "6.1.0(23)"。
问题 3:init() 返回错误码 201
原因:缺少权限。
检查清单:
- module.json5 是否声明了 CAMERA、GYROSCOPE、ACCELEROMETER 三个权限?
- 是否在代码中调用了
requestPermissionsFromUser请求 CAMERA? - 手机上是否已安装/更新 AR Engine 应用?
问题 4:相机画面正常但始终检测不到人体
排查步骤:
- 确认使用后置摄像头(
cameraLensFacing: 0)- 大多数设备仅后置支持 Body Tracking - 确认有人在摄像头前 1.5-3 米范围内
- 确认光线充足(> 200 lux)
- 确认人体全身在画面中(不要被裁剪)
- 在
onFrameUpdate中打印bodies.length,观察是否始终为 0
问题 5:compatibleSdkVersion 和 releaseType 不匹配
原因:runtimeOS 字段配置错误或缺失。
解决:在工程级 build-profile.json5 的 products 中添加 "runtimeOS": "HarmonyOS",注意该字段只能写在工程级,模块级 build-profile.json5 中不要写。
九、开发效率工具
9.1 状态栏调试
在 AR 相机画面上叠加一个状态文本,显示帧计数和检测人数:
this.frameCount++;
this.statusText = '检测: ' + bodies.length +
' 人 / 帧#' + this.frameCount;
帧计数器持续增长 = AR 回调正常工作,帧计数器不动 = 回调未触发 = AR 会话异常。
9.2 HiLog 日志

import { hilog } from '@kit.PerformanceAnalysisKit';
const DOMAIN = 0x0001;
hilog.info(DOMAIN, 'BodyAR', 'ARView init success');
hilog.error(DOMAIN, 'BodyAR', 'Failed: %{public}s', errMsg);
通过 DevEco Studio 的 Log 面板筛选 Domain 查看。
十、小结
本文覆盖了从零搭建 BodyAR 项目的完整流程:
- 环境准备:DevEco Studio + HarmonyOS SDK API 23+ + AR Engine 手机应用
- 权限系统:3 个必要权限的 module.json5 声明 + CAMERA 运行时申请
- SDK 版本:compatibleSdkVersion 与目标手机 API Level 匹配
- 核心代码:BodyAREngine 会话封装 + ARViewCallback 帧回调 + ARView 组件
- 排查手册:5 个高频问题的解决方案
项目搭建完成后,深入理解 AR 会话的内部机制是写出稳定应用的前提——ARConfig 的每一项参数都直接影响追踪精度和功耗。
更多推荐




所有评论(0)