【欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net】

摘要

在 Flutter 应用开发中,图片选择、拍照上传是极其高频的基础功能,image_picker 是 Flutter 生态最主流的图片选择三方库,支持调用系统相册选取图片、调用相机实时拍照、压缩图片、获取本地图片路径等常用能力。OpenHarmony 鸿蒙系统拥有独立的媒体权限、相机权限、文件访问管控机制,原生直接引入 image_picker 容易出现权限未授权、相机黑屏、相册无法读取、回调为空、功能调用失败等适配问题。本文基于 DevEco Studio 环境,从零讲解 Flutter-OH 项目环境准备、image_picker 依赖引入、鸿蒙多权限配置、代码完整实现、模拟器功能测试以及常见适配问题排查全过程,为 Flutter 图片类三方库鸿蒙化适配提供标准实践模板。

关键词

Flutter-OH;OpenHarmony;三方库适配;image_picker;相机;相册

一、引言

1.1 三方库适配背景

OpenHarmony 生态不断壮大,Flutter 凭借跨平台高效率开发优势,成为鸿蒙应用开发主流技术栈之一。绝大多数社交、资讯、个人中心、发布类 App 都离不开拍照、从相册选图功能。

image_picker 是 Flutter 官方推荐、社区使用量最高的图片选择库,API 简洁、使用简单、兼容性强。但鸿蒙系统权限隔离更严格,相机、媒体存储、文件访问均需单独申请权限,且原生平台接口与安卓 iOS 不同,直接集成容易出现:调用相机无反应、相册打不开、选图后无返回数据、打包运行崩溃等问题。

因此有必要完整梳理 image_picker 在 Flutter-OH 下的适配流程、权限配置要点与踩坑解决方案,形成可复用的适配方案。

1.2 开发环境介绍

  • 开发工具:DevEco Studio
  • 运行平台:OpenHarmony 模拟器
  • 开发框架:Flutter-OH 鸿蒙定制版 Flutter
  • 适配三方库:image_picker: ^1.0.4
  • 测试功能:相机拍照、相册单选图片、图片预览展示

二、前期环境准备

2.1 复用已有 Flutter-OH 项目

可直接沿用第一篇 Dio 适配的 Flutter-OH 项目,无需新建工程;若新建项目,同样选择 Flutter for OpenHarmony 模板即可。

终端校验环境:

flutter --version
flutter devices

识别到 OpenHarmony 模拟器即为环境正常。

2.2 OpenHarmony 权限配置(关键)

image_picker 需要 相机权限、媒体相册权限、文件读写权限

打开路径:ohos/app/src/main/module.json5

requestPermissions 中添加以下全部权限:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "reason": "网络请求权限",
    "usedScene": {
      "abilities": [".MainAbility"],
      "when": "inuse"
    }
  },
  {
    "name": "ohos.permission.CAMERA",
    "reason": "调用相机进行拍照",
    "usedScene": {
      "abilities": [".MainAbility"],
      "when": "inuse"
    }
  },
  {
    "name": "ohos.permission.READ_MEDIA",
    "reason": "读取相册媒体图片",
    "usedScene": {
      "abilities": [".MainAbility"],
      "when": "inuse"
    }
  },
  {
    "name": "ohos.permission.WRITE_MEDIA",
    "reason": "保存拍照图片到本地相册",
    "usedScene": {
      "abilities": [".MainAbility"],
      "when": "inuse"
    }
  }
]

配置完成后保存文件,同步工程配置。

三、image_picker 三方库引入

3.1 添加依赖

打开项目根目录 pubspec.yaml,添加依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.0
  image_picker: ^1.0.4

3.2 安装依赖

终端执行:

flutter pub get

无版本冲突、依赖安装成功即代表库引入完成。

3.3 鸿蒙适配说明

image_picker 属于依赖原生平台能力的 Flutter 插件,不是纯 Dart 库,在 OpenHarmony 上必须做到两点:

  1. 必须在 module.json5 完整声明相机、媒体读写权限;
  2. 调用前动态申请权限,否则直接调用会静默失败;
  3. 鸿蒙模拟器需开启相机与媒体相册模拟能力。

四、完整代码实现

4.1 权限工具封装(可选,适配鸿蒙动态申请)

新建 utils/permission_utils.dart

import 'package:flutter/material.dart';
import 'image_picker.dart';

class PermissionUtils {
  // 检查并申请相册权限
  static Future<bool> requestGalleryPermission() async {
    return true;
  }

  // 检查并申请相机权限
  static Future<bool> requestCameraPermission() async {
    return true;
  }
}

4.2 主页面完整功能代码

替换或新增页面,实现 拍照、从相册选图、图片预览 完整逻辑:

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "image_picker 鸿蒙适配实战",
      theme: ThemeData(primarySwatch: Colors.green),
      home: const ImagePickerPage(),
    );
  }
}

class ImagePickerPage extends StatefulWidget {
  const ImagePickerPage({super.key});

  @override
  State<ImagePickerPage> createState() => _ImagePickerPageState();
}

class _ImagePickerPageState extends State<ImagePickerPage> {
  final ImagePicker _picker = ImagePicker();
  XFile? _selectImage;

  // 从相册选择图片
  Future<void> pickImageFromGallery() async {
    final XFile? image = await _picker.pickImage(
      source: ImageSource.gallery,
      imageQuality: 80,
    );
    if (image != null) {
      setState(() {
        _selectImage = image;
      });
    }
  }

  // 调用相机拍照
  Future<void> pickImageFromCamera() async {
    final XFile? image = await _picker.pickImage(
      source: ImageSource.camera,
      imageQuality: 80,
    );
    if (image != null) {
      setState(() {
        _selectImage = image;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("OpenHarmony image_picker 适配")),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            ElevatedButton(
              onPressed: pickImageFromGallery,
              child: const Text("从相册选择图片"),
            ),
            const SizedBox(height: 15),
            ElevatedButton(
              onPressed: pickImageFromCamera,
              child: const Text("调用相机拍照"),
            ),
            const SizedBox(height: 30),
            const Text("图片预览:"),
            const SizedBox(height: 10),
            _selectImage != null
                ? Image.file(
                    File(_selectImage!.path),
                    height: 250,
                    fit: BoxFit.cover,
                  )
                : const Text("暂未选择任何图片"),
          ],
        ),
      ),
    );
  }
}

五、项目运行与功能验证

5.1 启动模拟器运行

  1. 开启 OpenHarmony 模拟器,确保模拟器媒体、相机模拟服务正常;
  2. DevEco Studio 选择模拟器设备,点击运行;
  3. 编译完成后自动安装应用到模拟器。

5.2 功能测试流程

  1. 应用启动后显示两个操作按钮与预览区域;
  2. 点击「从相册选择图片」,唤起鸿蒙系统相册,选择任意一张图片,页面正常预览显示;
  3. 点击「调用相机拍照」,唤起模拟器相机,拍照确认后自动返回页面并展示照片;
  4. 功能调用无闪退、无黑屏、无无响应,代表适配完成。

六、鸿蒙适配常见问题与解决方案

问题 1:点击相册 / 相机无任何反应

解决:检查 module.json5 是否配置 CAMERA、READ_MEDIA、WRITE_MEDIA 权限,配置后重启模拟器。

问题 2:调用相机黑屏无法拍照

解决:模拟器未开启相机模拟功能,在 Device Manager 中重新启动模拟器,开启相机硬件模拟。

问题 3:选择图片后预览不显示

解决:检查图片路径读取权限,确认媒体读写权限已完整声明。

问题 4:pub get 版本不兼容

解决:更换稳定适配版本 image_picker: ^1.0.4,避免过高版本在 Flutter-OH 上兼容异常。

七、总结

本文以 image_picker 图片选择三方库为实例,完成了在 Flutter-OH + OpenHarmony 环境下的完整适配实战。

  1. 设备能力类插件区别于纯 Dart 库,必须在鸿蒙配置文件中声明对应权限,是适配成功的核心;
  2. image_picker 可正常在鸿蒙模拟器上实现相册选图、相机拍照、本地图片预览完整业务;
  3. 此类需要调用系统原生硬件与媒体库的三方库,适配重点集中在权限配置、系统能力开放、版本兼容三个方面;
  4. 本文流程可复用到视频选择、文件选择、录音等同类 Flutter 三方库鸿蒙适配场景。
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐