news 2026/5/8 15:02:33

Day10_开源鸿蒙_Flutter_for_OpenHarmony_离线笔记_全量备份导出导入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day10_开源鸿蒙_Flutter_for_OpenHarmony_离线笔记_全量备份导出导入

开源鸿蒙 Flutter for OpenHarmony:离线笔记收官(全量备份导出/导入)

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

离线笔记做到 Day9,单条笔记已经能导出/导入(二维码+复制文本)。
但到了真正“换机/重装/迁移”的场景,大家更需要的是:全量备份

Day10 收官把这件事补齐:
一键把当前数据库里所有笔记导出成一段 JSON 文本(复制到剪贴板),另一台设备/重装后直接粘贴导入恢复。

这篇的重点依然是“怎么把三方库用到位”,但全量备份本身不需要新增插件:

  • 数据来自sqflite
  • 私密笔记的密文字段照样备份(不会导出明文)
  • 复制/粘贴用 Flutter 自带剪贴板即可

1. 全量备份为什么要单独做(单条导出不够用)

单条导出的缺点很明显:

  • 50 条笔记要导出 50 次
  • 迁移成本高,容易漏

全量备份的目标只有一个:
一次复制,一次导入,全部恢复。


2. 备份格式(v=1):包含 salt + notes 数组

为了兼容 Day4 的私密笔记,我们把salt_b64一起带上。
全量备份结构如下:

{"v":1,"salt_b64":"xxxx","notes":[{"title":"xxx","content":"xxx","pinned":0,"is_private":0,"content_cipher":null,"content_nonce":null,"content_mac":null,"created_at":0,"updated_at":0}]}

关键点:

  • 普通笔记:content有明文
  • 私密笔记:content固定为空,密文在content_cipher/nonce/mac

所以全量导出不会“把私密内容明文泄露”。


3. DAO 增加 listAllNotes:一次性取出所有未删除笔记

📌 文件:lib/features/note/data/note_dao.dart

Future<List<Note>>listAllNotes()async{finaldb=await_db.database;finalrows=awaitdb.query('notes',where:'is_deleted = ?',whereArgs:const[0],orderBy:'pinned DESC, updated_at DESC',);returnrows.map(_fromRow).toList(growable:false);}

这里不设 limit:因为我们就是为了“全量”。


4. Repository 实现全量导出/导入

📌 文件:lib/features/note/data/note_repository.dart

4.1 导出:exportAllNotesAsJson()

Future<String>exportAllNotesAsJson()async{constsaltKey='private_pin_salt_b64';finalsaltB64=await_dao.appDb.getKv(saltKey);finalall=await_dao.listAllNotes();finalpayload=<String,Object?>{'v':1,'salt_b64':saltB64,'notes':all.map((note)=><String,Object?>{'title':note.title,'content':note.content,'pinned':note.pinned?1:0,'is_private':note.isPrivate?1:0,'content_cipher':note.contentCipher,'content_nonce':note.contentNonce,'content_mac':note.contentMac,'created_at':note.createdAt.millisecondsSinceEpoch,'updated_at':note.updatedAt.millisecondsSinceEpoch,}).toList(growable:false),};returnjsonEncode(payload);}

4.2 导入:importAllNotesFromJson(text)

导入逻辑也很直接:

  1. 解析 JSON,校验v
  2. 如果带了salt_b64,先写回app_kv
  3. 循环notes,逐条 insert
Future<int>importAllNotesFromJson(Stringtext)async{constsaltKey='private_pin_salt_b64';finalobj=jsonDecode(text);if(objis!Map)throwStateError('Invalid json');finalv=obj['v'];if(v!=1)throwStateError('Unsupported version');finalsaltB64=obj['salt_b64'];if(saltB64isString&&saltB64.isNotEmpty){await_dao.appDb.setKv(saltKey,saltB64);}finallist=obj['notes'];if(listis!List)throwStateError('Missing notes');varcount=0;for(finaliteminlist){if(itemis!Map)continue;...await_dao.insert(note);count++;}returncount;}

5. 新增一个“数据工具”页面:导出复制 + 粘贴导入

📌 文件:lib/features/debug/ui/data_tools_page.dart

5.1 一键导出:复制到剪贴板

finaltext=awaitwidget.repo.exportAllNotesAsJson();awaitClipboard.setData(ClipboardData(text:text));awaitshowToast('已复制全量备份');

5.2 粘贴导入:导入成功提示“导入了多少条”

finaln=awaitwidget.repo.importAllNotesFromJson(text);awaitshowToast('已导入$n条');Navigator.pop(context,true);

6. 入口:列表页右上角加一个“数据工具”按钮

📌 文件:lib/features/note/ui/notes_list_page.dart

IconButton(onPressed:()async{finalchanged=awaitNavigator.of(context).push<bool>(MaterialPageRoute(builder:(_)=>DataToolsPage(repo:_repo),),);if(changed==true&&mounted){await_controller.load();}},icon:constIcon(Icons.settings),tooltip:'数据工具',),

导入成功后返回列表自动刷新。


📷

7. 自测清单(Day10)

  • 创建几条普通笔记 + 私密笔记 + 置顶笔记
  • 打开“数据工具” → 点导出 → 粘贴到备忘录确认是一段 JSON
  • 清空应用数据/重装(或换设备)后 → 打开“数据工具” → 粘贴 JSON → 导入
  • 返回列表:
    • 笔记数量一致
    • 置顶排序仍然有效
    • 私密笔记仍然需要 PIN 才能看到正文(导入不会变明文)

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

帆软FineReport 11.0安装配置全攻略:从下载到管理员账号设置

帆软FineReport 11.0企业级部署指南&#xff1a;从环境准备到安全加固 在企业数字化转型浪潮中&#xff0c;商业智能(BI)工具已成为数据驱动决策的核心基础设施。作为国内市场份额领先的报表工具&#xff0c;帆软FineReport 11.0以其强大的数据可视化能力和灵活的部署选项&…

作者头像 李华
网站建设 2026/5/8 14:58:32

从IMS盛会到实验室实践:微波射频测量挑战与工程解决方案

1. 从一场盛会到日常实践&#xff1a;微波技术社区的连接与创新循环刚结束的2011年国际微波研讨会&#xff08;IMS&#xff09;确实让人印象深刻&#xff0c;但对我而言&#xff0c;会议结束从来不是句号&#xff0c;而是一个更深入实践的开始。那一周在巴尔的摩&#xff0c;与…

作者头像 李华
网站建设 2026/5/8 14:56:38

Windows PDF自动化处理:Poppler预编译包的5分钟快速入门指南

Windows PDF自动化处理&#xff1a;Poppler预编译包的5分钟快速入门指南 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 你是否曾在Windows上进行P…

作者头像 李华
网站建设 2026/5/8 14:56:20

3个步骤快速生成Beyond Compare 5密钥:完整授权激活终极方案

3个步骤快速生成Beyond Compare 5密钥&#xff1a;完整授权激活终极方案 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen 你是否正在寻找一个简单可靠的方法来解除Beyond Compare 5的30天试用限制…

作者头像 李华
网站建设 2026/5/8 14:55:29

小团队避坑指南:靠数字边境,轻松搞定内容安全审核

作为创业公司的管理者&#xff0c;带小团队这几年&#xff0c;踩过不少隐形的坑&#xff0c;其中最让我后怕的&#xff0c;就是「内容安全」。以前总觉得&#xff0c;内容审核是大厂的事&#xff0c;我们小团队用户少、业务简单&#xff0c;没必要花精力在这上面&#xff0c;直…

作者头像 李华