@capacitor/camera 插件在鸿蒙PC平台的适配实践

@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 封装了插件安装的完整流程:

bash 复制代码
hionic plugin add @capacitor/camera

该命令会:

  1. 安装 npm 包 @capacitor/camera
  2. 自动检测并安装对应的 OpenHarmony 适配包 @capacitor-ohos/camera
  3. 注册插件到 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 中添加相机权限声明:

json5 复制代码
{
  "module": {
    ...
    "requestPermissions": [
      {
        "name": "ohos.permission.CAMERA",
        "reason": "$string:camera_permission",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      }
    ],
  }
}

注意user_grant 类型的权限(如相机、定位)必须 同时声明 reasonusedScene,否则编译会报错。

3.2 string.json

openharmony/entry/src/main/resources/base/element/string.json 添加权限说明文本:

json 复制代码
{
  "name": "camera_permission",
  "value": "Allow access to camera for taking photos"
}

4. 前端代码示例

4.1 动态导入策略

src/App.jsx 中,我们使用 动态 import() 而非顶层 import

jsx 复制代码
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 组件

jsx 复制代码
<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.jsnative-bridge.js),导致原生插件(相机等)无法与 Web 端通信。

5.3 解决方案

第一步:修正 webDir
json 复制代码
// capacitor.config.json
{
  "appId": "com.nutpi.MyApp",
  "appName": "MyHarmonyApp",
  "webDir": "dist"
}
第二步:补充桥接文件

index.html 中添加桥接脚本引用:

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>
第三步:构建 + 同步脚本

完整的发布流程:

bash 复制代码
# 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.jsonwebDir 必须与前端构建输出目录一致
桥接文件 cordova.js + native-bridge.js 必须跟随 Web 资源一起部署到 rawfile
权限声明 user_grant 权限需要同时声明 reasonusedScene
构建顺序 前端构建 → 同步资源 → 编译原生 → 部署,不能跳过中间步骤

9. 项目开源地址

本文对应的完整项目代码已开源:

🔗 https://atomgit.com/jianguoxu/hionic

包含已集成的 @capacitor/camera 插件、完整的 React 前端示例、OpenSSL 预编译库,以及从零到一的部署教程。


参考资源

相关推荐
想你依然心痛1 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“链界智脑“——PC端AI智能体沉浸式区块链智能合约审计与DeFi风控管理工作台
人工智能·区块链·ar·harmonyos·智能体
夜勤月1 小时前
深入解析 HarmonyOS 6 悬浮导航 2.0 与沉浸光感引擎
华为·harmonyos
yuegu7772 小时前
HarmonyOS应用<节气通>开发第7篇:文章详情页开发
华为·harmonyos
李二。2 小时前
鸿蒙原生ArkTS布局方式之ColumnEnd垂直排列
华为·harmonyos
yumgpkpm2 小时前
华为HUAWEI昇腾910B下千问Qwen3.6-27B在的推理加速实践
sql·华为·langchain·json·ai编程·ai写作·gpu算力
zhangfeng11332 小时前
DeepSeek V4 适配华为昇腾950 难度及开源情况
人工智能·pytorch·python·机器学习·华为·开源
G_dou_2 小时前
Flutter+OpenHarmony实战level_tool水平仪
flutter·harmonyos
TrisighT2 小时前
uni-app鸿蒙原生应用开发实战(下):核心功能实现与技术细节
vue.js·harmonyos
G_dou_2 小时前
Flutter三方库适配OpenHarmony【dice_roller】骰子投掷器项目完整实战
flutter·harmonyos