第103篇 | HarmonyOS 结营复盘:从相机 Demo 到多端智能记忆应用

第 103 篇是这个阶段的收束。项目从一个相机 Demo 出发,逐步接入地图、相册、保险箱、AI、视频、系统分享、近场分享、华为账号和端云同步。真正值得保留的不是功能数量,而是每一步都能回到用户路径和工程边界。

结营复盘要回答三个问题:这个项目解决了什么用户问题,哪些能力已经形成闭环,哪些能力仍需要真机和线上环境继续验证。

版本与环境

本文复测口径为 DevEco Studio 6.1 Release、HarmonyOS SDK 6.1.0(23)、Stage 模型 ArkTS 页面。涉及相机、地图、AI 在线能力、华为账号、系统分享或多端同步时,以真机结果为准;预览器只能用来检查页面结构和文案层级,不能替代权限、设备能力和系统弹窗验证。

对应源码位置

  • entry/src/main/module.json5
  • entry/src/main/ets/pages/Index.ets
  • entry/src/main/ets/services/GallerySyncService.ets
  • entry/src/main/ets/services/VolcengineArkService.ets

本篇目标

  • 从产品路线而不是 API 清单复盘项目。
  • 确认多设备、隐私、AI、端云同步四条主线各自的边界。
  • 把还需要真机复验的点列清楚。
  • 为后续发布、开源和社区答疑留下路线图。

先确认项目不是手机单形态 Demo

module.json5 里声明了 phone、tablet、2in1,说明项目从配置层就考虑了多设备入口。结营复盘时要把这个前提讲清楚:多端不是最后加一张平板截图,而是从窗口模式、导航宽度、内容约束开始设计。

如果后续要继续扩展 PC 或折叠屏,第一件事仍然是检查配置、窗口指标和页面布局是否一起更新。

项目从配置层声明 phone、tablet、2in1 和窗口模式

项目从配置层声明 phone、tablet、2in1 和窗口模式

    "deviceTypes": [
      "phone",
      "tablet",
      "2in1"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "metadata": [
      {
        "name": "client_id",
        "value": "6917602606633938955"
      }
    ],
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:foreground",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "supportWindowMode": [
          "fullscreen",
          "split",
          "floating"
        ],

端云同步把单机记忆变成可恢复资产

GallerySyncService 把身份、快照、记录和视频放进同一套同步模型里。它不是简单上传数组,而是要处理 ownerKey、schemaVersion、cloudReady、localMirror 和 cloudFoundation。

这条主线说明项目已经从本地相机走向可恢复资产,但也意味着账号切换、冲突合并和云端失败都必须被认真验收。

端云同步让相册记录和视频记录从单机状态变成可恢复资产

端云同步让相册记录和视频记录从单机状态变成可恢复资产


export type GallerySyncMode = 'localMirror' | 'cloudFoundation';

export interface HuaweiCredentialSeed {
  unionID?: string;
  openID?: string;
  idToken?: string;
  authorizationCode?: string;
  displayName?: string;
  nickName?: string;
  email?: string;
}

export interface GalleryAccountIdentity {
  userKey: string;
  displayName: string;
  source: 'huawei';
  loginAt: number;
  tokenHint: string;
}

export interface GallerySyncSnapshot {
  schemaVersion: number;
  ownerKey: string;
  mode: GallerySyncMode;
  updatedAt: number;
  records: Array<GalleryMoment>;
  videos: Array<GalleryVideoRecord>;
}

export interface GallerySyncRuntimeState {
  mode: GallerySyncMode;
  statusText: string;
  syncedAt: number;
  photoCount: number;
  videoCount: number;
  cloudReady: boolean;
}

export interface GallerySyncResult {
  records: Array<GalleryMoment>;
  videos: Array<GalleryVideoRecord>;
  state: GallerySyncRuntimeState;
}

interface GalleryCloudSnapshot {
  records: Array<GalleryMoment>;
  videos: Array<GalleryVideoRecord>;
}

interface GalleryAssetSize {
  width: number;
  height: number;
}

export class GallerySyncService {
  private static readonly STORE_NAME: string = 'super_image_gallery_sync';
  private static readonly IDENTITY_KEY: string = 'gallery_sync_identity';
  private static readonly STATE_KEY: string = 'gallery_sync_state';

AI 能力必须保留离线兜底

VolcengineArkService 接入图像理解、文案生成、视频生成和图片生成,但这些能力都依赖网络、Key 和服务端模型。结营复盘里不能只写“已接入 AI”,还要写清离线图解、本地提示词和失败恢复。

AI 是增强能力,不应该成为相册、地图和保险箱主链路的单点故障。

AI 输出需要解析、校验和本地兜底,不能破坏原始记录

AI 输出需要解析、校验和本地兜底,不能破坏原始记录

  private static parseInsight(rawText: string, record: GalleryMoment): VolcengineImageInsight {
    const jsonBlock = VolcengineArkService.extractJsonBlock(rawText);
    if (jsonBlock.length > 0) {
      try {
        const parsed = JSON.parse(jsonBlock) as ArkInsightPayload;
        if (parsed.aiCaption && parsed.videoPrompt) {
          return {
            aiCaption: parsed.aiCaption.trim(),
            videoPrompt: parsed.videoPrompt.trim(),
            rawText: rawText
          };
        }
      } catch (error) {
        console.error(`Failed to parse Ark insight JSON: ${JSON.stringify(error)}`);
      }
    }

    const fallbackText = VolcengineArkService.sanitizeProductText(rawText);
    return {
      aiCaption: fallbackText.length > 0
        ? fallbackText.slice(0, 80)
        : VolcengineArkService.buildFallbackCaption(record),
      videoPrompt: `以 ${record.place} 的照片为主场景,沿用原图人物、物体、光影和空间结构做 6 秒回忆短片,轻微运镜,不新增无关物体。`,
      rawText: rawText
    };
  }

  private static extractJsonBlock(rawText: string): string {
    const firstBrace = rawText.indexOf('{');
    const lastBrace = rawText.lastIndexOf('}');

最终路线图要能被真机复验

结营复盘最后要落到一张验收路线图:拍照、相册、地图、AI、视频、保险箱、分享、端云同步。每个节点都要有成功态、失败态和下一步动作。

这张路线图也是 6.14 文章发布后的社区答疑依据。有人问“支持什么设备”“失败怎么办”“隐私怎么处理”,都能回到这张表和对应源码入口。

结营复盘把项目从相机 Demo 收束为可复验的智能记忆应用

结营复盘把项目从相机 Demo 收束为可复验的智能记忆应用

    if (this.cloudSyncBusy) {
      return;
    }
    this.cloudSyncBusy = true;
    this.cloudSyncStatusText = this.cloudSyncIdentity ? '正在同步照片...' : '请先使用华为账号一键登录';
    try {
      const ready = await this.ensureHuaweiIdentityForCloudSync();
      if (!ready || !this.cloudSyncIdentity) {
        if (this.cloudSyncStatusText.indexOf('华为账号') < 0) {
          this.cloudSyncStatusText = '请先使用华为账号一键登录';
        }
        return;
      }

      this.cloudSyncStatusText = reason === 'login' ? '正在恢复照片...' : '正在同步照片...';
      const result = await GallerySyncService.mergeSnapshot(
        this.getAbilityContext(),
        this.cloudSyncIdentity,
        this.galleryRecords,
        this.videoManagerRecords
      );
      await GalleryRecordService.saveRecords(this.getAbilityContext(), result.records);
      await GalleryVideoService.saveRecords(this.getAbilityContext(), result.videos);
      const savedRecords = await GalleryRecordService.loadRecords(this.getAbilityContext());
      const savedVideos = await GalleryVideoService.loadRecords(this.getAbilityContext());
      await this.applyGalleryRecords(savedRecords);
      this.videoManagerRecords = savedVideos;
      this.updateCloudSyncState(result.state);
    } catch (error) {
      const err = error as BusinessError;
      this.cloudSyncStatusText = this.buildCloudSyncFriendlyMessage(err);
      console.error(`Failed to sync gallery cloud data: ${JSON.stringify(error)}`);
    } finally {
      this.cloudSyncBusy = false;
    }
  }

真机验收步骤

验收点 操作 预期结果
多端入口 检查 module.json5 和窗口模式 phone、tablet、2in1 入口清楚
隐私边界 未解锁保险箱时点击私密详情 不渲染私密图片和导出按钮
AI 兜底 清空 Key 或断网后使用图解功能 保留本地文案,不破坏原始记录
端云同步 登录华为账号后同步,再切换账号 状态文案清楚,冲突可恢复

复现边界

端云同步、华为账号、近场分享、DLP 防窥、在线 AI 都需要真机、账号或网络环境配合。结营复盘只说明工程链路和验收方法,不把外部服务可用性写成绝对承诺。

后续继续发布时,仍要以 CSDN 后台数据质量分和社区同步状态为最终验收,不以本地文章估算作为结果。

社区同步摘要

社区同步摘要可以写:本文复盘双镜记忆相机如何从相机 Demo 延展到多设备、隐私保护、AI 增强和端云同步,并给出每条能力的真机验收边界。

今日练习

  1. 把项目路线图压缩成一张“成功态/失败态/源码入口”表。
  2. 找出仍依赖真机或在线环境的能力,分别写出降级文案。
  3. 准备一段 120 秒结营讲解稿,按用户路径而不是 API 顺序介绍。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐