跳到主要内容

使用Picker选择媒体库资源

当用户需要分享图片、视频等文件时,开发者可以通过特定接口拉起系统图库,让用户自行选择待分享的资源,完成分享。此接口本身无需申请权限,目前适用于界面UIAbility,使用窗口组件触发。具体使用方式如下:

Media Library Kit提供图片和视频的管理能力,当需要读取和保存音频文件时,请使用AudioViewPicker(音频选择器对象)

  1. 导入选择器模块和文件管理模块。

    import { fileIo } from '@kit.CoreFileKit';
    import { photoAccessHelper } from '@kit.MediaLibraryKit';
  2. 创建图片-音频类型文件选择选项实例。

    const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  3. 配置可选的媒体文件类型和媒体文件的最大数目。

以下示例以图片选择为例,媒体文件类型请参见PhotoViewMIMETypes

photoSelectOptions.maxSelectNumber = 5;
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
photoSelectOptions.isPhotoTakingSupported = true;
  1. 创建图库选择器实例,调用PhotoViewPicker.select接口拉起图库界面进行文件选择。文件选择成功后,返回PhotoSelectResult结果集。

    const result = await photoViewPicker.select(photoSelectOptions);

    // 文件选择成功后,返回PhotoSelectResult结果集
    console.info('选择成功,返回结果: ' + JSON.stringify(result));
    console.info('选择的文件数量: ' + result.photoUris.length);

    // 更新选中的URI列表
    this.selectedUris = result.photoUris;
    // 设置默认选中第一个URI用于读取操作
    if (this.selectedUris.length > 0) {
    this.selectedUriForRead = this.selectedUris[0];
    }

    // 调用工具类处理结果
    this.processedItems = MediaLibraryPickerUtils.handleSelectResult(this.selectedUris);
    console.info('处理后的结果数量: ' + this.processedItems.length);

    select返回的uri权限是只读权限,可以根据结果集中uri进行读取文件数据操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,类似使用一个按钮去触发打开文件。可参考指定URI读取文件数据

    也可以通过返回的uri获取图片或视频资源

    如有获取元数据需求,可以通过文件管理接口文件URI根据uri获取部分文件属性信息,比如文件大小、访问时间、修改时间、文件名、文件路径等。

指定URI读取文件数据

  1. 待界面从图库返回后,再通过一个类似按钮的组件去调用其他函数,使用fileIo.openSync接口,通过媒体文件uri打开这个文件得到fd。这里需要注意接口权限参数是fileIo.OpenMode.READ_ONLY。

    try {
    const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
    console.info('file fd: ' + file.fd);
    return { fd: file.fd, file: file };
    } catch (error) {
    console.error('openSync failed with err: ' + error);
    return null;
    }
  2. 通过fd使用fileIo.readSync接口读取这个文件内的数据,读取完成后关闭fd。

    try {
    const buffer = new ArrayBuffer(bufferSize);
    const readLen = fileIo.readSync(fileObj.fd, buffer);
    console.info('readSync data to file succeed and buffer size is:' + readLen);
    return { data: buffer, length: readLen };
    } catch (error) {
    console.error('readSync failed with err: ' + error);
    return null;
    }

指定URI获取图片或视频资源

媒体库支持Picker选择媒体文件URI后,根据指定URI获取图片或视频资源,下面以查询指定URI为'file://media/Photo/1/IMG_datetime_0001/displayName.jpg'为例。

  1. 定义媒体资源处理器MediaAssetDataHandler,系统在资源准备就绪时向应用回调onDataPrepared。

    export class MediaAssetDataHandler implements photoAccessHelper.MediaAssetDataHandler<ArrayBuffer> {
    private callback?: MediaDataHandlerCallback;

    constructor(callback?: MediaDataHandlerCallback) {
    this.callback = callback;
    }

    // 使用箭头函数确保this引用不会丢失
    onDataPrepared = (data: ArrayBuffer) => {
    if (data === undefined) {
    console.error('Error occurred when preparing data');
    return;
    }
    console.info('on image data prepared');
    // 现在this始终指向MediaAssetDataHandler实例
    if (this.callback) {
    this.callback(data);
    }
    };
    }
  2. 使用getAssets接口获取要访问的资产,并通过requestImageData获取对应资源。

    出于对用户隐私安全的保护,对媒体资源EXIF中的地理位置和拍摄参数信息做了去隐私化处理。如果需要获取被去隐私化的EXIF信息,需要申请相册管理模块权限'ohos.permission.MEDIA_LOCATION'。

    static async getMediaResourceByUri(uri: string, context: common.Context, callback?: MediaDataHandlerCallback)
    : Promise<void> {
    try {
    // 创建PhotoAccessHelper实例
    const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

    // 创建查询条件
    const predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uri);

    // 设置查询选项
    const fetchOptions: photoAccessHelper.FetchOptions = {
    fetchColumns: [photoAccessHelper.PhotoKeys.TITLE],
    predicates: predicates
    };

    // 查询资产
    const fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> =
    await phAccessHelper.getAssets(fetchOptions);

    const photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
    if (photoAsset) {
    console.info('getAssets photoAsset.uri : ' + photoAsset.uri);
    // 获取标题属性
    console.info('title : ' + photoAsset.get(photoAccessHelper.PhotoKeys.TITLE));

    // 设置请求选项
    const requestOptions: photoAccessHelper.RequestOptions = {
    deliveryMode: photoAccessHelper.DeliveryMode.HIGH_QUALITY_MODE,
    };

    // 请求图片数据
    await photoAccessHelper.MediaAssetManager.requestImageData(
    context, photoAsset, requestOptions, new MediaAssetDataHandler(callback));

    console.info('requestImageData successfully');
    } else {
    console.error('No asset found for URI: ' + uri);
    }

    // 关闭查询结果
    fetchResult.close();
    } catch (err) {
    console.error('getMediaResourceByUri failed with err: ' + err);
    }
    }