news 2026/6/4 15:32:57

鸿蒙 Flutter 实战:saver_gallery 5.1.0 适配 3.27-ohos 全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙 Flutter 实战:saver_gallery 5.1.0 适配 3.27-ohos 全流程

摘要

在鸿蒙(OpenHarmony)Flutter3.27-ohos生态下,saver_gallery 是常用的保存图片/视频到系统相册插件。上游 5.x 已内置ohos/实现,但 SDK 约束面向 Flutter 3.44+。本文记录在Flutter 3.27.5-ohos-1.0.3上,将 saver_gallery ^5.1.0 跑通编译并完成 Demo 验证的过程,涵盖环境、依赖对齐、构建与接入方式。

开源仓库(计划):https://gitcode.com/xiaoyangming/flutter_saver_gallery_ohos


一、为什么要做这件事?

image_picker等插件解决的是从相册选图/选视频;业务里还常见反向需求:把截图、下载的图片或视频写回系统相册saver_gallery正是补齐这一环。

能力说明
saveImage将图片字节(PNG/JPG/GIF 等)保存到相册
saveFile将本地文件(视频、图片等)保存到相册
saveImages/saveFiles批量保存
SaveResult返回savedUri/savedUris等保存结果
clearCache清理插件临时缓存目录

典型场景:分享海报截图、保存网络图片、缓存视频后入库相册。

鸿蒙 Flutter 使用ohos平台实现。上游从4.0.0起已包含ohos/原生层,但 pub 上 5.x 声明 Flutter>=3.44.0、Dart>=3.12.0,无法直接在3.27-ohos工具链(Dart 3.6.2)上使用。本文目标是在3.27.5-ohos-1.0.3上完成 SDK 约束对齐、example 依赖修复与 HAP 编译验证。


二、环境与参考

2.1 开发环境

版本 / 说明
Flutter3.27.5-ohos-1.0.3
Dart3.6.2
命令flutter(本地若用 FVM,将下文flutter改为fvm flutter即可)
IDEDevEco Studio(鸿蒙签名、真机调试)

验证 Flutter 版本:

flutter--version

2.2 参考与发布仓库

仓库作用
fluttercandies/saver_gallery上游仓库(含ohos/实现)
xiaoyangming/flutter_saver_gallery_ohos本文适配成果对外发布(计划)
pub.dev/saver_gallery上游 Dart API(5.1.0)
openharmony-sig/flutter_image_gallery_saver同类旧 API 插件,可作对比参考

三、适配思路(3.27-ohos)

  1. 浅克隆上游仓库(git clone --depth 1)作为基线,保留已有SaverGalleryPlugin.ets
  2. pubspec.yaml中 SDK 约束从上游的>=3.44.0放宽至>=3.0.0 <4.0.0,以匹配 3.27-ohos。
  3. 修复 example 中与 Dart 3.6.2 冲突的dependency_overrides(见下文第四节)。
  4. 清除 examplebuild-profile.json5中无效的他人签名路径,避免 Hvigor 编译失败。
  5. 执行pub getanalyzebuild hap完成编译级验证;真机保存能力需在 DevEco 签名后进一步验证。

工程关键目录:

flutter_saver_gallery_ohos/ ├── lib/ # Dart API(包名仍为 saver_gallery) ├── ohos/ # 鸿蒙 HAR、SaverGalleryPlugin 原生实现 ├── example/ │ ├── lib/main.dart # 保存截图 / 网络图 / 视频 / GIF 演示 │ └── ohos/ # 示例 App,在此配置签名 └── pubspec.yaml

3.1 鸿蒙原生实现要点

OHOS 侧通过photoAccessHelper.showAssetsCreationDialog弹出系统授权对话框,用户确认后将沙箱文件复制到媒体库目标 URI。这意味着:

  • example 通常只需声明ohos.permission.INTERNET(网络下载示例)。
  • 无需module.json5中声明READ_IMAGEVIDEO等读相册权限。
  • 保存时用户会在系统弹窗中确认,体验与 Android 13+ 的 MediaStore 授权类似。

MethodChannel 名称与上游一致:com.fluttercandies/saver_gallery


四、适配过程中的关键修改

4.1 SDK 约束放宽

插件pubspec.yaml

environment:sdk:'>=3.0.0 <4.0.0'flutter:">=3.0.0"

上游 5.1.0 原声明 Flutter>=3.44.0、Dart>=3.12.0;本适配在不改 Dart API 语义的前提下放宽约束,以通过 3.27-ohos 的pub getanalyze

4.2 Example 依赖对齐

example 需额外接入鸿蒙生态下的 git 源插件(path_providerpermission_handlerdevice_info_plus等)。适配过程中移除以下与Dart 3.6.2冲突的 override:

移除项原因
path_provider_android: ^2.3.1依赖jni_flutter,要求 Flutter ≥3.35
win32: ^5.15.0依赖ffi ^2.1.4,要求 Dart ≥3.7

同时将diodependency_overrides改为正式依赖(example 下载网络图片/视频时使用)。


五、接入项目

5.1 添加依赖

在业务工程pubspec.yaml中:

dependencies:saver_gallery:git:url:https://gitcode.com/xiaoyangming/flutter_saver_gallery_ohos.gitref:v5.1.0-ohos-3.27

说明:Git 仓库名计划为flutter_saver_gallery_ohos,Dartpackage 名仍是saver_gallery,无需改 import。

flutter pub get

5.2 权限说明(OHOS)

保存到相册走系统弹窗授权,不需要提前申请读相册权限。

5.3 代码示例

import'dart:typed_data';import'package:saver_gallery/saver_gallery.dart';// 保存图片字节finalresult=awaitSaverGallery.saveImage(imageBytes,fileName:'screenshot.jpg',quality:80,skipIfExists:false,);print(result.isSuccess?result.savedUri:result.errorMessage);// 保存本地视频文件finalfileResult=awaitSaverGallery.saveFile(filePath:'/data/storage/.../video.mp4',fileName:'downloaded_video.mp4',skipIfExists:true,);// 批量保存finalbatchResult=awaitSaverGallery.saveFiles(files:[SaveFileItem(filePath:path1,fileName:'a.gif'),SaveFileItem(filePath:path2,fileName:'b.gif'),],skipIfExists:false,);

六、构建与签名

6.1 编译 HAP

cdexample flutter pub get flutter build hap--debug

编译通过时,HvigorassembleHap任务成功;若尚未配置签名,CLI 可能提示:

请通过DevEco Studio打开ohos工程后配置调试签名 (File -> Project Structure -> Signing Configs 勾选Automatically generate signature)

此时assembleHap 编译已通过,仅需在 DevEco 配置签名后即可产出可安装的 HAP。

6.2 DevEco 签名目录

签名请在example 的鸿蒙工程配置:

example/ohos/

步骤:File → Project Structure → Signing Configs → Automatically generate signature

七、真机功能验证(Demo)

仓库example提供以下按钮,建议真机按序测试并截图:

步骤操作对应 API
1Save Local ImagesaveImage(RepaintBoundary 截图)
2Save Network ImagesaveImage+ 网络下载
3Save Network VideosaveFile+ 临时目录
4Save Gif to AlbumsaveImage(GIF 字节)
5Save Two Gifs并行两次saveImage

每次保存时,系统应弹出媒体库创建授权对话框;用户确认后,可在系统相册中看到新文件。


3.27-ohos 已验证项(编译级)

  • flutter pub get/analyze无 error
  • flutter build hap --debug→ HvigorassembleHap成功
  • 真机保存:待 DevEco 签名后补截图(阶段 3)

八、与上游 / 其他平台的差异说明

对比项上游 pub 5.1.0本文(3.27-ohos)
Flutter SDK>=3.44.03.27.5-ohos-1.0.3
Dart SDK>=3.12.0>=3.0.0 <4.0.0(Dart 3.6.2)
包版本5.1.0对齐5.1.0
ohos 原生层上游自带沿用上游SaverGalleryPlugin.ets

鸿蒙 API 支持情况(编译与代码审查,节选):

API / 组件ohos 3.27
SaverGallery.saveImage
SaverGallery.saveFile
SaverGallery.saveImages/saveFiles
SaveResult.savedUri/savedUris
SaverGallery.clearCache
albumPath/relativePath⚠️OHOS 原生层当前未处理,保存到默认相册;Android/iOS 支持子目录

九、常见问题

Q1:build hap提示 Invalid storeFile / 签名路径不存在?
检查example/ohos/build-profile.json5是否含有他人机器的绝对路径;清空signingConfigs后在 DevEco 重新配置自动签名。

Q2:pub getpath_provider_androidwin32版本冲突?
勿在 3.27-ohos 工程中使用要求 Flutter 3.35+ / Dart 3.7+ 的 override;OHOS 构建依赖path_provider_ohosgit 源即可。

Q3:保存时没有反应?
确认已弹出系统授权对话框且用户点击允许;若 CLI 仅编译通过但未签名,需先在 DevEco 签名后再安装真机 HAP。

Q4:albumPath在鸿蒙上不生效?
当前 OHOS 实现未映射albumPath,文件会保存到系统默认相册位置;若业务强依赖自定义相册目录,需在SaverGalleryPlugin.ets中后续补齐。

Q5:依赖报错找不到saver_gallery
确认git地址为 flutter_saver_gallery_ohos,且已flutter pub get


十、参考链接

  • 插件仓库(计划):https://gitcode.com/xiaoyangming/flutter_saver_gallery_ohos
  • 上游仓库:https://github.com/fluttercandies/saver_gallery
  • 上游包:https://pub.dev/packages/saver_gallery
  • 适配笔记 / Demo:https://gitcode.com/xym_git/CSDN.git
  • AtomGit:https://atomcode.atomgit.com

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 15:32:45

从0开始转入Ai应用层,从python学起第六天

一、集合 (Set) 核心定义 集合是一个无序、不重复的元素序列。元素之间用逗号分隔&#xff0c;用 {} 或 set() 函数创建。 核心特性&#xff1a; 自动去重&#xff08;重复元素只保留一个&#xff09;元素必须是不可变类型&#xff08;不能放列表、字典&#xff09;无序&#x…

作者头像 李华
网站建设 2026/6/4 15:31:13

轨道赛车赛道维护:三步恢复导电性能,提升竞速体验

1. 项目概述&#xff1a;当你的轨道赛车开始“力不从心”玩轨道槽赛车&#xff08;Slot Car Racing&#xff09;的朋友&#xff0c;尤其是那些家里有一套玩了几年甚至十几年的老轨道的&#xff0c;肯定都遇到过这样的场景&#xff1a;赛车跑着跑着突然“卡顿”一下&#xff0c;…

作者头像 李华
网站建设 2026/6/4 15:30:50

Arduino驱动16x2 LCD显示屏:从硬件连接到动态显示实战指南

1. 项目概述与核心价值如果你刚开始玩Arduino&#xff0c;想让你的项目“开口说话”&#xff0c;或者至少能显示点信息&#xff0c;那么搞懂一块16x2的LCD显示屏绝对是绕不开的一步。这玩意儿在电子爱好者的世界里&#xff0c;地位堪比螺丝刀和万用表&#xff0c;是构建人机交互…

作者头像 李华
网站建设 2026/6/4 15:30:31

Python OOP 核心概念:从零到写出优雅代码,这一篇就够了

你是不是也遇到过这种情况&#xff1a;写了一堆 Python 脚本&#xff0c;功能都能跑&#xff0c;但代码越写越长&#xff0c;改一个地方要翻半天&#xff0c;同事看了直摇头&#xff1f;别急&#xff0c;这不是你菜&#xff0c;是你还没用上面向对象编程&#xff08;OOP&#x…

作者头像 李华
网站建设 2026/6/4 15:30:05

基于ESP8266与WS2811的六边形物联网时钟制作全攻略

1. 项目概述与核心思路最近在工作室里捣鼓一个桌面摆件&#xff0c;想做个既有科技感又实用的时钟。市面上那些数码管或者点阵屏的时钟看多了总觉得有点单调&#xff0c;于是把目光投向了可编程的RGB LED。最终决定动手做一个基于六边形像素矩阵的物联网时钟&#xff0c;核心就…

作者头像 李华
网站建设 2026/6/4 15:30:03

从零打造可穿戴发光眼镜:Arduino与NeoPixel的硬件创客实践

1. 项目概述&#xff1a;从动漫灵感到一个会发光的可穿戴道具作为一名喜欢鼓捣点硬件的创客&#xff0c;我经常在动漫和游戏里找灵感。前段时间&#xff0c;为了给一个《暗黑血统》里镰刀的道具找参考图&#xff0c;我偶然发现了《RWBY》这部动画。里面角色Maria Calavera那副标…

作者头像 李华