@capacitor/camera 插件在鸿蒙PC平台的适配实践
要点说明动态 import使用而不是静态 import,兼容浏览器开发模式webDir 一致性的webDir必须与前端构建输出目录一致桥接文件cordova.js必须跟随 Web 资源一起部署到 rawfile权限声明user_grant权限需要同时声明reason和usedScene构建顺序前端构建 → 同步资源 → 编译原生 → 部署,不能跳过中间步骤。
@capacitor/camera 插件在鸿蒙PC平台的适配实践
使用 hionic CLI 在 React + Capacitor 项目中集成相机插件,以及踩坑实录
背景
在之前的文章中,我们完成了从零到一将 React 应用部署到鸿蒙 PC 平台。本文聚焦于 Capacitor 插件 的使用 —— 以 @capacitor/camera 为例,演示如何安装、配置和调试插件,并分享在适配过程中遇到的关键问题与解决方案。
1. 项目结构回顾
MyApp/
├── src/ # React 前端源码
├── dist/ # Vite 构建产物
├── openharmony/ # OpenHarmony 原生工程
│ ├── entry/ # 应用主模块
│ │ └── src/main/
│ │ └── resources/
│ │ └── rawfile/
│ │ └── www/ # Web 资源(由 dist/ + 桥接文件组成)
│ └── capacitor/ # Capacitor 适配层(C++ + ArkTS)
├── capacitor.config.json # Capacitor 配置
└── package.json
2. 安装 @capacitor/camera 插件
hionic CLI 封装了插件安装的完整流程:
hionic plugin add @capacitor/camera
该命令会:
- 安装 npm 包
@capacitor/camera - 自动检测并安装对应的 OpenHarmony 适配包
@capacitor-ohos/camera - 注册插件到 CMakeLists.txt(C++ 层)和
capacitor.plugins.json
安装后的目录变化:
openharmony/capacitor/src/main/cpp/
├── Camera/ # 新增相机插件 C++ 适配层
├── getcapacitor/ # 核心桥接
└── HotCodePushPlugin/ # 热更新
3. 配置相机权限
3.1 module.json5
编辑 openharmony/entry/src/main/module.json5,在 requestPermissions 中添加相机权限声明:
{
"module": {
...
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_permission",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
],
}
}
注意:
user_grant类型的权限(如相机、定位)必须同时声明reason和usedScene,否则编译会报错。
3.2 string.json
在 openharmony/entry/src/main/resources/base/element/string.json 添加权限说明文本:
{
"name": "camera_permission",
"value": "Allow access to camera for taking photos"
}
4. 前端代码示例
4.1 动态导入策略
在 src/App.jsx 中,我们使用 动态 import() 而非顶层 import:
const takePhoto = async () => {
try {
setError(null)
const { Camera } = await import('@capacitor/camera')
const image = await Camera.getPhoto({
quality: 90,
allowEditing: false,
resultType: 'DataUrl',
})
setPhoto(image.dataUrl)
} catch (err) {
setError(`Camera error: ${err.message}`)
}
}
这样做的好处:在 npm run dev 浏览器开发模式下,页面不会因找不到 Capacitor 运行时而直接崩溃;只有点击按钮时才会尝试加载插件,在浏览器中优雅降级为错误提示。
4.2 UI 组件
<section id="camera-demo">
<h2>📸 Camera Demo</h2>
<p>Test the <code>@capacitor/camera</code> plugin on your device</p>
<button onClick={takePhoto}>Take Photo</button>
{error && <p className="camera-error">{error}</p>}
{photo && (
<div className="photo-preview">
<img src={photo} alt="Captured" />
</div>
)}
</section>
5. 关键踩坑:Web 资源同步
5.1 问题现象
在完成前端开发和插件安装后,部署到设备发现 相机按钮没有出现。打开的是旧页面。
5.2 根因分析
hionic start capacitor 生成的项目存在一个配置断层:
capacitor.config.json → webDir: "www"
Vite 构建输出 → dist/
openharmony rawfile → rawfile/www/
三者之间的指向关系不一致:
| 环节 | 实际目录 | 问题 |
|---|---|---|
| Vite 默认输出 | dist/ |
与 Capacitor 配置不匹配 |
capacitor.config.json |
webDir: "www" |
但 www/ 目录不存在 |
| OHOS rawfile | rawfile/www/ |
存的是旧模板文件 |
同时,React 构建产物中缺少 Capacitor 桥接文件(cordova.js、native-bridge.js),导致原生插件(相机等)无法与 Web 端通信。
5.3 解决方案
第一步:修正 webDir
// capacitor.config.json
{
"appId": "com.nutpi.MyApp",
"appName": "MyHarmonyApp",
"webDir": "dist"
}
第二步:补充桥接文件
在 index.html 中添加桥接脚本引用:
<body>
<div id="root"></div>
<script src="./cordova.js"></script>
<script src="./native-bridge.js"></script>
<script type="module" src="/src/main.jsx"></script>
</body>
第三步:构建 + 同步脚本
完整的发布流程:
# 1. 构建前端
npx vite build
# 2. 复制桥接文件到构建目录(从 git 历史或 node_modules 恢复)
cp cordova.js native-bridge.js cordova_plugins.js dist/
# 3. 同步到 OHOS rawfile
rm -rf openharmony/entry/src/main/resources/rawfile/www
cp -r dist openharmony/entry/src/main/resources/rawfile/www
# 4. 编译原生 HAP
cd openharmony
hvigorw assembleHap
# 5. 部署到设备
hionic run openharmony
6. 完整开发工作流
hionic plugin add @capacitor/camera
│
▼
配置权限 (module.json5 + string.json)
│
▼
编写前端代码 (src/App.jsx)
│
▼
vite build → 复制桥接文件 → 同步到 rawfile
│
▼
hvigor assembleHap ← 编译原生工程
│
▼
hionic run openharmony ← 部署到设备
7. 验证结果
编译输出:
> hvigor BUILD SUCCESSFUL in 10 s 778 ms
HAP 产物:
openharmony/entry/build/default/outputs/default/
├── entry-default-signed.hap (26.3 MB)
└── entry-default-unsigned.hap (26.3 MB)
部署后设备上显示:
- 📸 Camera Demo 区域
- Take Photo 按钮
- 点击后弹出相机权限请求
- 拍照后照片回显在页面中
8. 技术要点总结
| 要点 | 说明 |
|---|---|
| 动态 import | 使用 await import('@capacitor/camera') 而不是静态 import,兼容浏览器开发模式 |
| webDir 一致性 | capacitor.config.json 的 webDir 必须与前端构建输出目录一致 |
| 桥接文件 | cordova.js + native-bridge.js 必须跟随 Web 资源一起部署到 rawfile |
| 权限声明 | user_grant 权限需要同时声明 reason 和 usedScene |
| 构建顺序 | 前端构建 → 同步资源 → 编译原生 → 部署,不能跳过中间步骤 |
9. 项目开源地址
本文对应的完整项目代码已开源:
🔗 https://atomgit.com/jianguoxu/hionic
包含已集成的 @capacitor/camera 插件、完整的 React 前端示例、OpenSSL 预编译库,以及从零到一的部署教程。
参考资源
- hionic CLI 仓库:https://atomgit.com/CPF-Ionic/capacitor-cli
- @capacitor/camera 官方文档:https://capacitorjs.com/docs/apis/camera
更多推荐



所有评论(0)