HarmonyOS Developer 媒体库管理

丶龙八夷
发布于 2023-3-31 16:38
浏览
0收藏

媒体库开发概述

MediaLibrary提供媒体库相关能力,帮助开发者更方便地访问和修改媒体文件,具体分为:

      ○ 查询指定媒体资源

      ○ 获取图片/视频

      ○ 获取图片/视频缩略图

      ○ 创建媒体资源

      ○ 重命名媒体资源

      ○ 将媒体资源放入回收站

      ○ 获取文件保存的公共目录

      ○ 沙箱与公共路径间文件的复制

      ○ 读写文件内容

      ○ 获取相册中的图片/视频

      ○ 创建相册

      ○ 重命名相册

说明

本开发指导基于API Version 9,仅适用于Stage模型。

应用需要先获取媒体库实例,才能访问和修改用户等个人媒体数据信息。媒体库涉及用户个人数据信息,所以应用需要向用户申请媒体库读写操作权限才能保证功能的正常运行。

开发者在使用MediaLibrary进行功能开发前,请先掌握以下内容:

  • 获取媒体库实例
  • 申请媒体库功能相关权限

获取媒体库实例

应用需要使用应用上下文Context通过接口​​getMediaLibrary​​,获取媒体库实例,用于访问和修改用户等个人媒体数据信息(如音频、视频、图片、文档等)。

开发步骤

  1. 导入mediaLibrary模块以使用媒体库相关接口。
  2. 通过getContext获取应用上下文。
  3. 获取媒体库实例。

import mediaLibrary from '@ohos.multimedia.mediaLibrary';

const context = getContext(this);
var media = mediaLibrary.getMediaLibrary(context);

申请媒体库功能相关权限

媒体库的读写操作需要相应权限,在申请权限前,请保证符合​​权限使用的基本原则​​。涉及的权限如下表。

权限名

说明

授权方式

ohos.permission.READ_MEDIA

允许应用读取用户外部存储中的媒体文件信息。

user_grant

ohos.permission.WRITE_MEDIA

允许应用读写用户外部存储中的媒体文件信息。

user_grant

ohos.permission.MEDIA_LOCATION

允许应用访问用户媒体文件中的地理位置信息。

user_grant

以上权限的授权方式均为user_grant(用户授权),即开发者在module.json5文件中配置对应的权限后,需要使用接口​​abilityAccessCtrl.requestPermissionsFromUser​​去校验当前用户是否已授权。如果是,应用可以直接访问/操作目标对象;否则需要弹框向用户申请授权。

说明

即使用户曾经授予权限,应用在调用受此权限保护的接口前,也应该先检查是否有权限。不能把之前授予的状态持久化,因为用户在动态授予后还可以通过“设置”取消应用的权限。

开发步骤

  1. 在配置文件module.json5中声明权限。在配置文件的“module”标签内,增加“requestPermissions”标签,标签内容请根据实际情况填写。标签说明可参考​​访问控制(权限)开发指导​​。

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.MEDIA_LOCATION",
        "reason": "$string:reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.READ_MEDIA",
        "reason": "$string:reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.WRITE_MEDIA",
        "reason": "$string:reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      }
    ]
  }
}    
  1. 在Ability.ts中onWindowStageCreate里调用requestPermissionsFromUser进行权限校验,可以选择需要动态申请获取的权限自行添加相应代码。

import UIAbility from '@ohos.app.ability.UIAbility';
import abilityAccessCtrl, {Permissions} from '@ohos.abilityAccessCtrl';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage) {
    let list : Array<Permissions> = ['ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA'];
    let permissionRequestResult;
    let atManager = abilityAccessCtrl.createAtManager();
    atManager.requestPermissionsFromUser(this.context, list, (err, result) => {
      if (err) {
        console.error('requestPermissionsFromUserError: ' + JSON.stringify(err));
      } else {
        permissionRequestResult = result;
        console.info('permissionRequestResult: ' + JSON.stringify(permissionRequestResult));
      }
    });       
  }
}

媒体资源使用指导

应用可以通过mediaLibrary的接口,进行媒体资源(音频、视频、图片文件等)相关操作。

说明

在进行功能开发前,请开发者查阅​​媒体库开发概述​​,了解如何获取媒体库实例和如何申请媒体库功能开发相关权限。

为了保证应用的运行效率,大部分MediaLibrary调用都是异步的,对于异步调用的API均提供了callback和Promise两种方式,以下示例均采用Promise函数,更多方式可以查阅​​API参考​​。

获取媒体资源

开发者可以根据特定的条件查询媒体资源,如指定类型、指定日期、指定相册等。

应用通过调用​​MediaLibrary.getFileAssets​​获取媒体资源,并传入MediaFetchOptions对象指定检索条件。MediaFetchOptions.selections为检索条件,使用FileKey中的枚举值作为检索条件的列名;MediaFetchOptions.selectionArgs对应selections中检索条件列的值;除此之外,可以使用order(结果排序方式)、uri(文件URI)、networkId(注册设备网络ID)作为检索条件。

如果只想获取某个位置的对象(如第一个、最后一个、指定索引等),可以通过​​FetchFileResult​​中的接口获取对应位置的媒体资源对象。本小节均采用getNextObject循环获取检索结果中的所有媒体资源。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读权限“ohos.permission.READ_MEDIA”。

指定媒体类型

下面以查询图片类型的媒体资源为例。

开发步骤

selections: FileKey.MEDIA_TYPE,根据媒体类型检索。

selectionArgs: MediaType.IMAGE,媒体类型为图片。

async function example() {
  let fileKeyObj = mediaLibrary.FileKey;
  let fileType = mediaLibrary.MediaType.IMAGE;
  let option = {
    selections: fileKeyObj.MEDIA_TYPE + '= ?',
    selectionArgs: [fileType.toString()],
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const fetchFileResult = await media.getFileAssets(option);
  fetchFileResult.getFirstObject().then((fileAsset) => {
    console.log('getFirstObject.displayName : ' + fileAsset.displayName);
    for (let i = 1; i < fetchFileResult.getCount(); i++) {
      fetchFileResult.getNextObject().then((fileAsset) => {
        console.info('fileAsset.displayName ' + i + ': ' + fileAsset.displayName);
      }).catch((err) => {
        console.error('Failed to get next object: ' + err);
      });
    }
  }).catch((err) => {
    console.error('Failed to get first object: ' + err);
  });
}
指定日期

下面以查询指定添加日期的媒体资源为例。实际开发中可以设置添加日期、修改日期、拍摄日期。

selections: FileKey.DATE_ADDED,根据文件添加日期检索。

selectionArgs:2022-8-5,具体添加时间的字符串。

async function example() {
  let fileKeyObj = mediaLibrary.FileKey;
  let option = {
    selections: fileKeyObj.DATE_ADDED + '> ?',
    selectionArgs: ['2022-8-5'],
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const fetchFileResult = await media.getFileAssets(option);
  fetchFileResult.getFirstObject().then((fileAsset) => {
    console.info('getFirstObject.displayName : ' + fileAsset.displayName);
    for (let i = 1; i < fetchFileResult.getCount(); i++) {
      fetchFileResult.getNextObject().then((fileAsset) => {
        console.info('fileAsset.displayName ' + i + ': ' + fileAsset.displayName);
      }).catch((err) => {
        console.error('Failed to get next object: ' + err);
      });
    }
  }).catch((err) => {
    console.error('Failed to get first object: ' + err);
  });
}
按指定顺序排列

下面以查询图片并按文件添加日期降序排列为例。实际开发中可以设置升序(AESC)和降序(DESC)。

order: FileKey.DATE_ADDED,根据文件添加日期排序;并设置排列顺序为DESC降序。

async function example() {
  let fileKeyObj = mediaLibrary.FileKey;
  let fileType = mediaLibrary.MediaType.IMAGE;
  let option = {
    selections: fileKeyObj.MEDIA_TYPE + '= ?',
    selectionArgs: [fileType.toString()],
    order: fileKeyObj.DATE_ADDED + " DESC",
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const fetchFileResult = await media.getFileAssets(option);
  fetchFileResult.getFirstObject().then((fileAsset) => {
    console.info('getFirstObject.displayName : ' + fileAsset.displayName);
    for (let i = 1; i < fetchFileResult.getCount(); i++) {
      fetchFileResult.getNextObject().then((fileAsset) => {
        console.info('fileAsset.displayName ' + i + ': ' + fileAsset.displayName);
      }).catch((err) => {
        console.error('Failed to get next object: ' + err);
      });
    }
  }).catch((err) => {
    console.error('Failed to get first object: ' + err);
  });
}
指定相册

下面以指定相册myAlbum为例。

selections: FileKey.ALBUM_NAME,根据相册名称检索。

selectionArgs:'myAlbum',具体相册名称。

async function example() {
  let fileKeyObj = mediaLibrary.FileKey;
  let option = {
    selections: fileKeyObj.ALBUM_NAME + '= ?',
    selectionArgs: ['myAlbum'],
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const fetchFileResult = await media.getFileAssets(option);
  if (albumList.length > 0) {
    fetchFileResult.getFirstObject().then((album) => {
      console.info('getFirstObject.displayName : ' + album.albumName);
    }).catch((err) => {
      console.error('Failed to get first object: ' + err);
    });
  } else {
    console.info('getAlbum list is: 0');
  }
}

获取相册中的图片或视频

获取相册的媒体资源有两种方式,一是通过​​MediaLibrary.getFileAssets​​​指定相册以获取媒体资源,参考获取指定相册的媒体资源;二是通过​​Album.getFileAssets​​使用相册Album实例获取媒体资源。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读权限“ohos.permission.READ_MEDIA”。

开发步骤

下面以获取相册名称为“新建相册1”的视频为例。

  1. 建立检索条件,用于获取目的相册实例。

let fileKeyObj = mediaLibrary.FileKey;
let AlbumNoArgsFetchOp = {
  selections: fileKeyObj.ALBUM_NAME + '= ?',
  selectionArgs: ['新建相册1']
}
  1. 建立检索条件,用于获取目的相册下的视频资源。

let fileKeyObj = mediaLibrary.FileKey;
let videoType = mediaLibrary.MediaType.VIDEO;
let videoFetchOp  = {
  selections: fileKeyObj.MEDIA_TYPE + '= ?',
  selectionArgs: [videoType.toString()],
}
  1. 通过Album.getFileAssets获取对应的资源。

以下为完整示例

async function getCameraImagePromise() {
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let fileKeyObj = mediaLibrary.FileKey;
  let videoType = mediaLibrary.MediaType.VIDEO;
  let videoFetchOp = {
    selections: fileKeyObj.MEDIA_TYPE + '= ?',
    selectionArgs: [videoType.toString()],
  }
  let AlbumNoArgsFetchOp = {
    selections: fileKeyObj.ALBUM_NAME + '= ?',
    selectionArgs: ['新建相册1']
  }

  let albumList = await media.getAlbums(AlbumNoArgsFetchOp);
  if (albumList.length > 0) {
    const album = albumList[0];
    let fetchFileResult = await album.getFileAssets(videoFetchOp);
    let count = fetchFileResult.getCount();
    console.info("get mediaLibrary VIDEO number", count);
  } else {
    console.info('getAlbum list is: 0');
  }
}

获取图片/视频缩略图

通过接口​​FileAsset.getThumbnail​​,传入缩略图尺寸,可以获取图片/视频缩略图。缩略图常用于UI界面展示。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读权限“ohos.permission.READ_MEDIA”。

获取某张图片的缩略图

当需要在相册展示图片/视频、编辑预览,应用需要获取某张图片的缩略图。

下面以获取相册第一张图片的缩略图为例,缩略图尺寸为720*720。

开发步骤

  1. 建立检索条件,用于获取目的相册下的图片资源。
  2. 调用getFileAssets获取目标图片资源。
  3. 调用getFirstObject获取第一张图片。
  4. 调用getThumbnail获取相册中图片的缩略图。

async function getFirstThumbnailPromise() {
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let fileKeyObj = mediaLibrary.FileKey;
  let imageType = mediaLibrary.MediaType.IMAGE;
  let imagesFetchOp = {
    selections: fileKeyObj.MEDIA_TYPE + '= ?',
    selectionArgs: [imageType.toString()],
  }

  let size = { width: 720, height: 720 };
  const fetchFileResult = await media.getFileAssets(imagesFetchOp);
  if (fetchFileResult === undefined) {
    console.error("get image failed with error");
    return;
  } else {
    const asset = await fetchFileResult.getFirstObject();
    asset.getThumbnail(size).then((pixelMap) => {
      pixelMap.getImageInfo().then((info) => {
        console.info('get Thumbnail info: ' + "width: " + info.size.width + " height: " + info.size.height);
      }).catch((err) => {
        console.error("getImageInfo failed with error: " + err);
      });
    }).catch((err) => {
      console.error("getImageInfo failed with error: " + err);
    });
  }
}

创建媒体资源

通过接口​​MediaLibrary.createAsset​​可以创建媒体资源。

前提条件

下面以创建文件类型(MediaType.FILE)的文件为例。

async function example() {
  let mediaType = mediaLibrary.MediaType.FILE;
  let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_DOCUMENTS;
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const path = await media.getPublicDirectory(DIR_DOCUMENTS);
  media.createAsset(mediaType, "testFile.text", path).then((asset) => {
    console.info("createAsset successfully:"+ JSON.stringify(asset));
  }).catch((err) => {
    console.error("createAsset failed with error: " + err);
  });
}

将文件放入回收站

通过​​FileAsset.trash​​可以将文件放入回收站。

放入回收站的文件将会保存30天,在此期间,开发者可以将trash的入参isTrash设置为false将其恢复为正常文件;应用用户也可以通过系统应用“文件管理”或“图库”恢复文件。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读写权限“ohos.permission.WRITE_MEDIA”。

下面以将文件检索结果中第一个文件放入回收站为例。

开发步骤

  1. 建立检索条件,用于获取目的相册下的图片资源。
  2. 调用getFileAssets获取目标图片资源。
  3. 调用getFirstObject获取第一张图片,即要放入回收站的图片对象。
  4. 调用trash将文件放入回收站。

async function example() {
  let fileKeyObj = mediaLibrary.FileKey;
  let fileType = mediaLibrary.MediaType.FILE;
  let option = {
    selections: fileKeyObj.MEDIA_TYPE + '= ?',
    selectionArgs: [fileType.toString()],
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const fetchFileResult = await media.getFileAssets(option);
  let asset = await fetchFileResult.getFirstObject();
  if (asset === undefined) {
    console.error('asset not exist');
    return;
  }
  //回调为空
  asset.trash(true).then(() => {
    console.info("trash successfully");
  }).catch((err) => {
    console.error("trash failed with error: " + err);
  });
}

重命名媒体资源

重命名修改的是文件的FileAsset.displayName属性,即文件的显示文件名,包含文件后缀。

修改后再通过​​FileAsset.commitModify​​更新到数据库中。

在重命名文件之前,需要先获取文件对象,可以通过​​FetchFileResult​​中的接口获取对应位置的文件。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读写权限“ohos.permission.WRITE_MEDIA”。

下面以将文件检索结果中第一个文件重命名为“newtitle.text”为例。

开发步骤

  1. 建立检索条件,用于获取目的相册下的图片资源。
  2. 调用getFileAssets获取目标图片资源。
  3. 调用getFirstObject获取第一张图片,即要重命名的图片对象。
  4. 将图片重命名为“newImage.jpg“。
  5. 调用FileAsset.commitModify将更新的图片属性修改到数据库中。

async function example() {
  let fileKeyObj = mediaLibrary.FileKey;
  let fileType = mediaLibrary.MediaType.IMAGE;
  let option = {
    selections: fileKeyObj.MEDIA_TYPE + '= ?',
    selectionArgs: [fileType.toString()],
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const fetchFileResult = await media.getFileAssets(option);
  let asset = await fetchFileResult.getFirstObject();
  if (asset === undefined) {
    console.error('asset not exist');
    return;
  }
  asset.displayName = 'newImage.jpg';
  //回调为空
  asset.commitModify((err) => {
    if (err) {
      console.error('fileRename Failed ');
      return;
    }
    console.info('fileRename successful.');
  });
}

文件路径使用指导

HarmonyOS上用户数据统一由媒体库进行管理,用户数据用户数据可以通过mediaLibrary提供的接口能力进行访问和操作。

说明

在进行功能开发前,请开发者查阅​​媒体库开发概述​​,了解如何获取媒体库实例和如何申请媒体库功能开发相关权限。

为了保证应用的运行效率,大部分MediaLibrary调用都是异步的,对于异步调用的API均提供了callback和Promise两种方式,以下示例均采用Promise函数,更多方式可以查阅​​API参考​​。

公共目录路径支持的文件格式

在使用文件路径进行开发之前,需要了解各公共目录路径支持的文件格式说明。

注意

下表仅表示系统能识别的文件类型,在具体的开发中,开发者需要关注对应接口支持的文件格式。

如image编码功能只支持.jpeg和.webp,解码功能只支持.jpg .png .gif .bmp .webp RAW。

目录路径

目录类型

媒体类型

说明

支持的文件格式

Camera/

DIR_CAMERA

VIDEO amd IMAGE

相机拍摄图片与录像的存放路径,目录与子目录下可以存放视频,图片类型文件。

.bmp / .bm / .gif / .jpg /. jpeg / .jpe / .png / .webp / .raw / .svg / .heif / .mp4 / .3gp / .mpg / .mov / .webm / .mkv

Videos/

DIR_VIDEO

VIDEO

视频专有目录,目录与子目录下只可以存放视频类型文件。

.mp4 / .3gp / .mpg / .mov / .webm / .mkv

Pictures/

DIR_IMAGE

IMAGE

图片专有目录,目录与子目录下只可以存放图片类型文件。

.bmp / .bm / .gif / .jpg /. jpeg / .jpe / .png / .webp / .raw / .svg / .heif

Audios/

DIR_AUDIO

AUDIO

音频专有目录,目录与子目录下只可以存放音频类型文件。

.aac/.mp3/.flac/.wav/.ogg

Documents/

DIR_DOCUMENTS

FILE

文档类型目录,目录与子目录下只可以存放音频,图片,视频以外类型文件。

-

Download/

DIR_DOWNLOAD

ALLTYPE

下载文件存放目录,目录与子目录下文件类型不受限制。

-

获取文件保存的公共目录

不同类型的文件会保存到不同的公共目录下,可以通过接口​​getPublicDirectory​​来获取公共目录路径。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读权限“ohos.permission.READ_MEDIA”。

下面以获取Camera文件保存的公共目录为例。

async function example(){
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let DIR_CAMERA = mediaLibrary.DirectoryType.DIR_CAMERA;
  const dicResult = await media.getPublicDirectory(DIR_CAMERA);
  if (dicResult == 'Camera/') {
    console.info('mediaLibraryTest : getPublicDirectory passed');
  } else {
    console.error('mediaLibraryTest : getPublicDirectory failed');
  }
}

沙箱与公共路径间文件的复制

HarmonyOS提供应用沙箱机制,增加目录可见性数据访问防线,减少了应用数据和用户隐私信息泄露,建立了更加严格安全的应用沙盒隔离能力。

放在公共路径下的文件,用户可以通过系统应用“文件管理”、“图库”访问,但应用沙箱内的文件,只有应用本身可以访问。

复制文件

通过接口​​mediaLibrary.FileAsset.open​​可以打开公共路径文件。

通过接口​​fs.open​​可以打开沙箱路径文件,沙箱路径必须通过应用上下文context进行访问。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读写权限“ohos.permission.WRITE_MEDIA”。
  • 除了@ohos.multimedia.mediaLibrary外,还需要导入模块​​@ohos.file.fs​​。

开发步骤

  1. 调用​​context.filesDir​​获取应用沙箱路径。
  2. 调用MediaLibrary.getFileAssets和FetchFileResult.getFirstObject获取公共目录中的FileAsset实例。
  3. 调用fs.open打开沙箱路径文件。
  4. 调用fileAsset.open打开公共路径文件。
  5. 调用fs.copyfile复制文件。
  6. 调用fileAsset.close和fs.close关闭文件。

示例1 将公共路径文件复制到沙箱路径下

async function copyPublic2Sandbox() {
  try {
    const context = getContext(this);
    let media = mediaLibrary.getMediaLibrary(context);
    let sandboxDirPath = context.filesDir;
    let fileKeyObj = mediaLibrary.FileKey;
    let fileAssetFetchOp = {
      selections: fileKeyObj.DISPLAY_NAME + '= ?',
      selectionArgs: ['testFile.txt'],
    };
    let fetchResult = await media.getFileAssets(fileAssetFetchOp);
    let fileAsset = await fetchResult.getFirstObject();

    let fdPub = await fileAsset.open('rw');
    let fdSand = await fs.open(sandboxDirPath + '/testFile.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    await fs.copyFile(fdPub, fdSand.fd);

    await fileAsset.close(fdPub);
    await fs.close(fdSand.fd);

    let content_sand = await fs.readText(sandboxDirPath + '/testFile.txt');
    console.info('content read from sandbox file: ', content_sand)
  } catch (err) {
    console.info('[demo] copyPublic2Sandbox fail, err: ', err);
  }
}

示例2 将应用沙箱路径文件复制到公共路径

async function copySandbox2Public() {
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let sandboxDirPath = context.filesDir;

  let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_DOCUMENTS;
  const publicDirPath = await media.getPublicDirectory(DIR_DOCUMENTS);
  try {
    let fileAsset = await media.createAsset(mediaLibrary.MediaType.FILE, 'testFile02.txt', publicDirPath);
    console.info('createFile successfully, message = ' + fileAsset);
  } catch (err) {
    console.error('createFile failed, message = ' + err);
  }
  try {
    let fileKeyObj = mediaLibrary.FileKey;
    let fileAssetFetchOp = {
      selections: fileKeyObj.DISPLAY_NAME + '= ?',
      selectionArgs: ['testFile02.txt'],
    };
    let fetchResult = await media.getFileAssets(fileAssetFetchOp);
    var fileAsset = await fetchResult.getFirstObject();
  } catch (err) {
    console.error('file asset get failed, message = ' + err);
  }
  let fdPub = await fileAsset.open('rw');
  let fdSand = await fs.open(sandboxDirPath + 'testFile.txt', fs.OpenMode.READ_WRITE);
  await fs.copyFile(fdSand.fd, fdPub);
  await fileAsset.close(fdPub);
  await fs.close(fdSand.fd);
  let fdPubRead = await fileAsset.open('rw');
  try {
    let arrayBuffer = new ArrayBuffer(4096);
    await fs.read(fdPubRead, arrayBuffer);
    var content_pub = String.fromCharCode(...new Uint8Array(arrayBuffer));
    fileAsset.close(fdPubRead);
  } catch (err) {
    console.error('read text failed, message = ', err);
  }
  console.info('content read from public file: ', content_pub);
}
读写文件内容

通过​​mediaLibrary​​​的接口FileAsset.open和FileAsset.close可以打开和关闭文件。通过​​file.fs​​的接口fs.read和fs.write可以读写文件。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读写权限“ohos.permission.WRITE_MEDIA”和“ohos.permission.READ_MEDIA”。
  • 除了@ohos.multimedia.mediaLibrary外,还需要导入模块​​@ohos.file.fs​​。

开发步骤

  1. 创建用于读写示例的文件。

async function example() {
  let mediaType = mediaLibrary.MediaType.FILE;
  let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_DOCUMENTS;
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const path = await media.getPublicDirectory(DIR_DOCUMENTS);
  media.createAsset(mediaType, "testFile.text", path).then((asset) => {
    console.info("createAsset successfully:" + JSON.stringify(asset));
  }).catch((err) => {
    console.error("createAsset failed with error: " + err);
  });
}
  1. 使用open打开文件。
  2. 使用fs.write写入文件,以string形式传入写入数据。
  3. 使用fs.read读取文件,以 ArrayBuffer 形式保存读取结果。
  4. 将ArrayBuffer转化为string,以string形式得到文件内容。
  5. 使用close关闭文件。

示例1 打开现有文件、向文件中写入

async function writeOnlyPromise() {
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let fileKeyObj = mediaLibrary.FileKey;
  let fileAssetFetchOp = {
    selections: fileKeyObj.DISPLAY_NAME + '= ?',
    selectionArgs: ['testFile.txt'],
  };
  let fetchResult = await media.getFileAssets(fileAssetFetchOp);
  let fileAsset = await fetchResult.getFirstObject();
  console.info('fileAssetName: ', fileAsset.displayName);

  try {
    let fd = await fileAsset.open('w');
    console.info('file descriptor: ', fd);
    await fs.write(fd, "Write file test content.");
    await fileAsset.close(fd);
  } catch (err) {
    console.error('write file failed, message = ', err);
  }
}

示例2 打开现有文件,读取文件内容

async function readOnlyPromise() {
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let fileKeyObj = mediaLibrary.FileKey;
  let fileAssetFetchOp = {
    selections: fileKeyObj.DISPLAY_NAME + '= ?' ,
    selectionArgs: ['testFile.txt'],
  };
  let fetchResult = await media.getFileAssets(fileAssetFetchOp);
  let fileAsset = await fetchResult.getFirstObject();
  console.info('fileAssetName: ', fileAsset.displayName);

  try {
    let fd = await fileAsset.open('r');
    let arrayBuffer = new ArrayBuffer(4096);
    await fs.read(fd, arrayBuffer);
    let fileContent = String.fromCharCode(...new Uint8Array(arrayBuffer));
    globalThis.fileContent = fileContent;
    globalThis.fileName = fileAsset.displayName;
    console.info('file content: ', fileContent);
    await fileAsset.close(fd);
  } catch (err) {
    console.error('read file failed, message = ', err);
  }
}

相册资源使用指导

mediaLibrary提供相册相关的接口,供开发者创建、删除相册,获取相册中的图片资源等。

说明

在进行功能开发前,请开发者查阅​​媒体库开发概述​​,了解如何获取媒体库实例和如何申请媒体库功能开发相关权限。

为了保证应用的运行效率,大部分MediaLibrary调用都是异步的,对于异步调用的API均提供了callback和Promise两种方式,以下示例均采用Promise函数,更多方式可以查阅​​API参考​​。

获取相册中的图片/视频

获取相册中的图片、视频有两种方式:

一是通过​​MediaLibrary.getFileAssets​​​指定相册以获取媒体资源,参考​​获取指定相册的媒体资源​​;

二是通过​​Album.getFileAssets​​​使用相册Album实例获取媒体资源,参考​​获取相册中的图片或视频​​。

创建相册

通过​​MediaLibrary.createAsset​​可以创建媒体资源,可以通过创建图片或视频文件时设置的相对路径,创建出相册。相对路径的命名即为相册名称。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读写权限“ohos.permission.WRITE_MEDIA”。

下面以创建相册myAlbum为例。

开发步骤

  1. 调用getPublicDirectory获取文件公共路径。
    获取文件公共路径的更多指导可参考​​​获取文件保存的公共目录​​。
  2. 调用createAsset新建图片,并设置相对路径为path+'myAlbum/'。
    即在创建相册的同时,往里面放了一张图片。

async function example() {
  let mediaType = mediaLibrary.MediaType.IMAGE;
  let DIR_IMAGE = mediaLibrary.DirectoryType.DIR_IMAGE;
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  const path = await media.getPublicDirectory(DIR_IMAGE);
  //myAlbum为新建文件保存路径,也是新建相册的名称
  media.createAsset(mediaType, 'test.jpg', path + 'myAlbum/', (err, fileAsset) => {
    if (fileAsset === undefined) {
      console.error('createAlbum failed, message = ' + err);
    } else {
      console.info('createAlbum successfully, message = ' + JSON.stringify(fileAsset));
    }
  });
}

重命名相册

重命名修改的是相册的FileAsset.albumName属性,即相册名称。修改后再通过​​Album.commitModify​​更新到数据库中。

前提条件

  • 获取媒体库mediaLibrary实例。
  • 申请媒体库读写权限“ohos.permission.WRITE_MEDIA”。

下面以重命名相册为“newAlbum“为例。

开发步骤

  1. 建立检索条件,用于获取目标相册。
  2. 调用getAlbums获取相册列表。
  3. 将相册重命名为“newAlbum“。
  4. 调用Album.commitModify将更新的相册属性修改到数据库中。

async function example() {
  let AlbumNoArgsfetchOp = {
    selections: '',
    selectionArgs: [],
  };
  const context = getContext(this);
  let media = mediaLibrary.getMediaLibrary(context);
  let albumList = await media.getAlbums(AlbumNoArgsfetchOp);
  let album = albumList[0];
  album.albumName = 'newAlbum';
  //回调返回空
  album.commitModify().then(() => {
    console.info("albumRename successfully");
  }).catch((err) => {
    console.error("albumRename failed with error: " + err);
  });
}




文章转载自:​​https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/medialibrary-album-guidelines-0000001478061601-V3​

标签
已于2023-3-31 16:38:43修改
收藏
回复
举报
回复
    相关推荐