1 简介
Media Library Kit(媒体文件管理服务)提供了管理相册和媒体文件的能力。通过该服务,我们可以管理相册和媒体文件,包括创建相册以及访问、修改相册中的媒体信息等。
2 开发准备
2.1 申请权限
相册管理模块的读写操作需要相应权限。首先我们需要在module.json5文件中配置对应的权限。
权限名 | 说明 | 授权方式 |
ohos.permission.READ_IMAGEVIDEO | 允许应用读取媒体库的图片和视频媒体文件信息。 | user_grant |
ohos.permission.WRITE_IMAGEVIDEO | 允许应用读写媒体库的图片和视频媒体文件信息。 | user_grant |
然后,我们需要使用接口abilityAccessCtrl.requestPermissionsFromUser去校验当前用户是否已授权。如果是,应用可以直接访问/操作目标对象;否则需要弹框向用户申请授权。主要代码如下。
// 程序访问控制管理
const atManager = abilityAccessCtrl.createAtManager();
// 请求用户授权
const grantStatus = await atManager.requestPermissionsFromUser(getContext(), permissions)
2.2 获取相册管理模块实例
此处需要使用接口getPhotoAccessHelper,获取相册管理模块实例,用于访问和修改相册中媒体数据信息(如图片、视频)。该接口的getPhotoAccessHelper方法需要一个上下文参数,所以我们要先通过getContext获取应用上下文。主要代码如下。
import photoAccessHelper from '@ohos.file.photoAccessHelper';
// 此处获取的photoAccessHelper实例为全局对象,后续文档中使用到的地方默认为使用此处获取的对象,如未添加此段代码报未定义的错误请自行添加。
const context = getContext(this);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
3 媒体资源使用
3.1 获取指定媒体资源
开发者可以根据特定的条件查询媒体资源,如指定类型、指定日期、指定相册等。应用通过调用PhotoAccessHelper.getAssets获取媒体资源,并传入FetchOptions对象指定检索条件。其中FetchOptions中对应两个参数分别为fetchColumns(检索条件)和predicates(谓词查询)。fetchColumns一般置空,因为如果该参数为空时默认查询uri、name、photoType(具体字段名称以检索对象定义为准)。而predicates是我们主要的筛选条件,使用时需导入dataSharePredicates模块并实例化。dataSharePredicates模块也提供了很多接口辅助我们进行筛选,如常用的equalTo用于配置谓词以匹配值等于指定值的字段,orderByAsc用于配置谓词以匹配其值按升序排序的列,orderByDesc用于配置谓词以匹配其值按降序排序的列,in用于配置谓词以匹配值在指范围内的字段。
以查询文件名为'test.jpg'的图片资源为例,代码如下。
import dataSharePredicates from '@ohos.data.dataSharePredicates';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
const context = getContext(this);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
async function example() {
//导入dataSharePredicates模块
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
//谓词筛选与'test.jpg'同名文件
predicates.equalTo(photoAccessHelper.PhotoKeys.DISPLAY_NAME, 'test.jpg');
//定义FetchOptions检索条件
let fetchOptions: photoAccessHelper.FetchOptions = {
fetchColumns: [],
predicates: predicates
};
try {
//传入FetchOptions对象指定检索条件
let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
//选取结果集的第一个对象
let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
console.info('getAssets photoAsset.displayName : ' + photoAsset.displayName);
//释放FetchResult实例
fetchResult.close();
} catch (err) {
console.error('getAssets failed with err: ' + err);
}
}
3.2 使用Picker选择媒体库资源
用户有时需要分享图片、视频等用户文件,开发者可以通过特定接口拉起系统图库,用户自行选择待分享的资源,然后最终分享出去。此接口本身无需申请权限,目前适用于界面UIAbility,使用窗口组件触发。具体使用方式如下:
1、导入选择器模块和文件管理模块
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import fs from '@ohos.file.fs';
import { BusinessError } from '@ohos.base';
2、创建图片-音频类型文件选择选项实例
const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
3、选择媒体文件类型和选择媒体文件的最大数目
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为图片,也可设置为VIDEO_TYPE文件类型为视频,IMAGE_VIDEO_TYPE文件类型为图片和视频类型
photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目
4、创建图库选择器实例,调用PhotoViewPicker.select接口拉起图库界面进行文件选择。文件选择成功后,返回PhotoSelectResult结果集。
select返回的uri权限是只读权限,可以根据结果集中uri进行读取文件数据操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。
如有获取元数据需求,可以通过文件管理接口和文件URI根据uri获取部分文件属性信息,比如文件大小、访问时间、修改时间、文件名、文件路径等。
let uris: Array<string> = [];
const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
uris = photoSelectResult.photoUris;
console.info('photoViewPicker.select to file succeed and uris are:' + uris);
}).catch((err: BusinessError) => {
console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
5、待界面从图库返回后,再通过类似一个按钮调用其他函数,使用fs.openSync接口,通过uri打开这个文件得到fd。这里需要注意接口权限参数是fs.OpenMode.READ_ONLY。
//此处为单一uri,如上述获取uri数组的话,可使用ForEach进行遍历
let uri: string = '';
let file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
console.info('file fd: ' + file.fd);
6、通过fd使用fs.readSync接口读取这个文件内的数据,读取完成后关闭fd。
let buffer = new ArrayBuffer(4096);
let readLen = fs.readSync(file.fd, buffer);
console.info('readSync data to file succeed and buffer size is:' + readLen);
fs.closeSync(file);
4 相册资源使用
photoAccessHelper提供用户相册相关的接口,供开发者创建、删除用户相册,往用户相册中添加和删除图片和视频资源等。
4.1 获取用户相册
开发者通过PhotoAccessHelper.getAlbums接口获取用户相册。获取相册的方法和3.1中获取图片方法类似,也是通过谓词进行筛选。以获取一个相册名为'test'的用户相册为例,具体代码如下。
async function example() {
//创建predicates实例
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
//定义predicates
predicates.equalTo(photoAccessHelper.AlbumKeys.ALBUM_NAME, 'test');
//传入predicates到FetchOptions定义筛选条件
let fetchOptions: photoAccessHelper.FetchOptions = {
fetchColumns: [],
predicates: predicates
};
try {
//传入fetchOptions参数进行筛选,获取用户相册
let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions);
//获取结果集的第一个对象
let album: photoAccessHelper.Album = await fetchResult.getFirstObject();
console.info('getAlbums successfully, albumName: ' + album.albumName);
fetchResult.close();
} catch (err) {
console.error('getAlbums failed with err: ' + err);
}
}
4.2 添加图片和视频到用户相册中
先获取用户相册对象和需要添加到相册中的图片或视频的对象数组,然后调用MediaAlbumChangeRequest.addAssets和PhotoAccessHelper.applyChanges接口往用户相册中添加图片或视频。以向‘album’用户相册中添加路径为'photoAsset'的图片为例,主要代码如下。
//实例化MediaAlbumChangeRequest并传入'album'相册参数
let albumChangeRequest: photoAccessHelper.MediaAlbumChangeRequest = new photoAccessHelper.MediaAlbumChangeRequest(album);
//调用MediaAlbumChangeRequest.addAssets接口往用户相册中添加图片
albumChangeRequest.addAssets([photoAsset]);
//调用PhotoAccessHelper.applyChanges接口提交相册变更请求
await phAccessHelper.applyChanges(albumChangeRequest);
console.info('succeed to add ' + photoAsset.displayName + ' to ' + album.albumName);
//释放资源
albumFetchResult.close();
photoFetchResult.close()
4.3 获取用户相册中的图片和视频
当我们获取用户相册对象之后,只需调用Album.getAssets接口即可获取用户相册中的图片资源。下面以获取'album'用户相册中图片为例,主要代码如下。
建立图片检索条件,用于获取图片
let photoPredicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
let photoFetchOptions: photoAccessHelper.FetchOptions = {
fetchColumns: [],
predicates: photoPredicates
};
//调用Album.getAssets接口获取用户相册中的图片资源
let photoFetchResult = await album.getAssets(photoFetchOptions);
//调用FetchResult.getFirstObject接口获取第一张图片
let photoAsset = await photoFetchResult.getFirstObject();
4.4 从用户相册中移除图片和视频
在获取用户相册中的资源后,选择其中要移除的资源,然后调用MediaAlbumChangeRequest.removeAssets和PhotoAccessHelper.applyChanges接口移除。下面以删除'album'相册中'photoAsset'图片为例,具体代码如下所示。
//实例化对象
let albumChangeRequest: photoAccessHelper.MediaAlbumChangeRequest = new photoAccessHelper.MediaAlbumChangeRequest(album);
//调用MediaAlbumChangeRequest.removeAssets接口从用户相册中移除图片
albumChangeRequest.removeAssets([photoAsset]);
//调用PhotoAccessHelper.applyChanges接口提交相册变更请求
await phAccessHelper.applyChanges(albumChangeRequest);
console.info('succeed to remove ' + photoAsset.displayName + ' from ' + album.albumName);
//释放资源
albumFetchResult.close();
photoFetchResult.close();
5 结语
以上为本人对于HarmonyOS中的Media Library Kit(媒体文件管理服务)在实际开发中应用场景和使用方法的简单阐述,具体使用方法详见官方开发文档。
加油HD,我们一起共建鸿蒙生态!