HarmonyOS鸿蒙Next应用如何实现将图片或视频保存到用户相册?共有几种方式?请分别讲解使用步骤和源码

HarmonyOS鸿蒙Next应用如何实现将图片或视频保存到用户相册?共有几种方式?请分别讲解使用步骤和源码 移动应用开发中,将图片和视频,保存到用户的本地相册。是非常高频的操作。

请问鸿蒙应用如何实现将图片或视频保存到用户相册?共有几种方式?请分别讲解使用步骤和源码

3 回复

一、结论

共有三种方式实现该效果。分别是:

1、保存按钮 saveButton

2、保存弹框 showAssetsCreationDialog

3、读写权限处理

官方推荐前两种,第三种所需的读写很不好申请到。从用户体验和用户隐私安全角度考虑,前两者也是最优选择。

二、代码实现和详细解释

saveButton示例

import { photoAccessHelper } from '@kit.MediaLibraryKit';

@Entry
@Component
struct saveButtonExample {
    saveButtonOptions: SaveButtonOptions = {
    icon: SaveIconStyle.FULL_FILLED,
    text: SaveDescription.SAVE_IMAGE,
    buttonType: ButtonType.Capsule
  } // 设置安全控件按钮属性

  build() {
    Row() {
      Column() {
        SaveButton(this.saveButtonOptions) // 创建安全控件按钮
          .onClick(async (event, result: SaveButtonOnClickResult) => {
             if (result == SaveButtonOnClickResult.SUCCESS) {
               try {
                 let context = getContext();
                 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
                 // 需要确保fileUri对应的资源存在
                 let fileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';
                 let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);
                 await phAccessHelper.applyChanges(assetChangeRequest);
                 console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);
               } catch (err) {
                 console.error(`create asset failed with error: ${err.code}, ${err.message}`);
               }
             } else {
               console.error('SaveButtonOnClickResult create asset failed');
             }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

showAssetsCreationDialog示例

import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';

let context = getContext(this);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

async function showAssetsCreationDialogExample() {
  try {
    // 指定待保存到媒体库的位于应用沙箱的图片uri
    let srcFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';
    let srcFileUris: Array<string> = [
      srcFileUri
    ];
    // 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选
    let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
      {
        title: 'test', // 可选
        fileNameExtension: 'jpg',
        photoType: photoAccessHelper.PhotoType.IMAGE,
        subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
      }
    ];
    // 基于弹窗授权的方式获取媒体库的目标uri
    let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
    // 将来源于应用沙箱的照片内容写入媒体库的目标uri
    let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY);
    let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY);
    await fileIo.copyFile(srcFile.fd, desFile.fd);
    fileIo.closeSync(srcFile);
    fileIo.closeSync(desFile);
    console.info('create asset by dialog successfully');
  } catch (err) {
    console.error(`failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message}`);
  }
}

注意: 1. 使用createAsset需要指定是视频还是图片, fileio.open并不校验文件内容 2. 使用createImageAssetRequest接口,如果要保存视频需要用createVideoeAssetRequest 或者还可以直接使用createAssetRequest和addResource的方式

申请读写权限示例

需要申请"ohos.permission.READ_IMAGEVIDEO"和"ohos.permission.WRITE_IMAGEVIDEO"权限。该权限是管制权限,需要你的应用去通过场景申请【申请使用受限权限

配置权限READ_IMAGEVIDEO,WRITE_IMAGEVIDEO

"requestPermissions": [
  {
    "name": "ohos.permission.READ_IMAGEVIDEO",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when": "inuse"
    },
    "reason": "$string:CAMERA"
  },
  {
    "name": "ohos.permission.WRITE_IMAGEVIDEO",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when": "inuse"
    },
    "reason": "$string:CAMERA"
  }
]

向用户申请权限

//  创建申请权限明细
async reqPermissionsFromUser(): Promise<number[]> {
  let context = getContext() as common.UIAbilityContext;
  let atManager = abilityAccessCtrl.createAtManager();
  let grantStatus = await atManager.requestPermissionsFromUser(context, ['ohos.permission.READ_IMAGEVIDEO','ohos.permission.WRITE_IMAGEVIDEO']);
  return grantStatus.authResults;
}

// 用户申请权限
async requestPermission() {
  let grantStatus = await this.reqPermissionsFromUser();
  for (let i = 0; i < grantStatus.length; i++) {
    if (grantStatus[i] === 0) {
      // 用户授权,可以继续访问目标操作



    }
  }
}

保存图片到媒体库

public async savePicture(buffer: ArrayBuffer): Promise<void> {
  let helper : photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext(this) as common.UIAbilityContext);
  let options: photoAccessHelper.CreateOptions = {
    title: Date.now().toString()
  };
  let photoUri: string = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);
  console.info(photoUri)
  // createAsset的调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限
  let file: fs.File = fs.openSync(photoUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  await fs.write(file.fd, buffer);
  fs.closeSync(file);
}

更多关于HarmonyOS鸿蒙Next应用如何实现将图片或视频保存到用户相册?共有几种方式?请分别讲解使用步骤和源码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS Next中保存图片或视频到相册主要有两种方式:

  1. 使用媒体库管理接口 (MediaLibraryManager) 步骤:申请ohos.permission.READ_IMAGEVIDEOohos.permission.WRITE_IMAGEVIDEO权限。通过MediaLibraryManager.getMediaLibrary()获取实例,调用createAsset()创建媒体资源,并用openAsset()获取文件描述符后写入数据。

  2. 使用文件选择器保存 (PhotoViewPicker) 步骤:导入@ohos.file.picker模块。创建PhotoViewPicker实例,调用save()方法并传入SaveOptions参数(指定文件名称和类型)。系统会弹出保存界面,用户确认后返回保存文件的URI。

关键点:均需在module.json5中声明权限,并使用Stage模型。

在HarmonyOS Next中,将图片或视频保存到用户相册主要有两种方式:使用媒体库管理模块(@ohos.file.photoAccessHelper)和通过用户交互的“保存到相册”系统能力。下面分别讲解使用步骤和核心源码。

方式一:使用媒体库管理模块(photoAccessHelper)

此方式允许应用直接操作相册,需申请相册管理权限(ohos.permission.READ_IMAGEVIDEOohos.permission.WRITE_IMAGEVIDEO),适用于需要静默保存或批量处理的场景。

使用步骤:

  1. 申请权限:在module.json5中配置权限,并在运行时动态申请。
  2. 获取相册助手:通过photoAccessHelper.getPhotoAccessHelper获取PhotoAccessHelper实例。
  3. 创建媒体资源:使用createAsset方法在相册中创建图片或视频资源,并写入数据。

核心源码示例:

import photoAccessHelper from '@ohos.file.photoAccessHelper';
import fs from '@ohos.file.fs';

// 1. 获取相册助手实例(context为UIAbilityContext)
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

// 2. 定义创建资源的参数(以图片为例)
let createOption: photoAccessHelper.PhotoCreateOptions = {
  title: 'my_image.jpg' // 文件显示名
};

// 3. 创建资源并写入数据
let imageUri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', createOption);
let file = await fs.open(imageUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
// 假设imageData是已获取的图片ArrayBuffer
await fs.write(file.fd, imageData);
fs.close(file);

视频保存只需将PhotoType.IMAGE改为PhotoType.VIDEO,并对应调整扩展名(如.mp4)。

方式二:通过“保存到相册”系统能力

此方式会触发系统原生的保存界面,用户可自行选择相册目录,无需申请相册管理权限,更符合用户隐私预期。

使用步骤:

  1. 导入依赖模块:使用@kit.ArkUI中的Action能力。
  2. 构建保存请求:创建SaveRequest对象,指定要保存的URI数组。
  3. 调用系统能力:通过Action.saveAssets触发保存界面。

核心源码示例:

import { Action } from '@kit.ArkUI';

// 1. 准备要保存的媒体文件URI(可通过文件选择器或临时文件获取)
let uris: Array<string> = ['file://.../temp/image.jpg']; // 支持多个URI

// 2. 构建保存请求
let saveRequest: Action.SaveRequest = {
  assets: uris
};

// 3. 调用系统保存能力
try {
  await Action.saveAssets(context, saveRequest); // context为UIAbilityContext
  console.info('保存成功');
} catch (err) {
  console.error(`保存失败: ${err.code}, ${err.message}`);
}

总结与选择

  • 方式一(photoAccessHelper):需权限,适合后台静默保存。注意遵循权限最小化原则,并确保用户知晓操作。
  • 方式二(Action.saveAssets):无需权限,通过系统界面交互,用户体验更规范。推荐在用户主动触发保存时使用。

两种方式均支持图片(JPEG/PNG等)和视频(MP4等)格式,关键区别在于权限需求和用户交互流程。开发时请根据具体场景选择。

回到顶部