HarmonyOS开发-媒体文件管理服务
HarmonyOS开发-媒体文件管理服务
前言
前面我们在图片识别的时候需要读取本地图片,用户可以在本地图片中选取,也可以拍照,那么在这里,我们用到了文件管理的能力,这个能力是基于HarmonyOS提供的媒体文件管理服务(Media Library Kit),这个能力提供了管理相册和媒体文件的能力,包括图片和视频,帮助应用快速构建图片和视频的展示与播放能力,这里要注意,这个能力是特指在HarmonyOS中,在OpenHarmony中需要使用系统的文件基础服务(Core File Kit)
介绍
通过Media Library Kit,开发者可以管理相册和媒体文件,包括创建相册、访问和修改相册中的媒体信息。
面向所有应用开放如下能力:
- 选择/保存媒体库资源
- 使用Picker选择媒体库资源
- 保存媒体库资源
- 管理动态照片
- 访问和管理动态照片资源
- 使用MovingPhotoView播放动态照片
- 使用Picker组件
- 使用PhotoPicker组件访问图片/视频
- 使用AlbumPicker组件访问相册列表
- 使用RecentPhoto组件获取最近一张图片
- 使用PhotoPicker推荐图片
- 使用PickerController将编辑后的图片替换原图
在这里,我们讲解一下# PhotoPicker组件的使用过程和步骤,主要是用来访问相册和拍照,衔接上一个文章的能力,当应用需要读取用户图片时,开发者可以在应用界面中嵌入PhotoPicker组件,在用户选择所需要的图片资源后,直接返回该图片资源,而不需要授予应用读取图片文件的权限,即可完成图片或视频文件的访问和读取。
第一步:引入PhotoPicker模块文件
// 导入媒体库工具包相关组件与接口(中文注释版)
import {PhotoPickerComponent, // 照片选择器组件(核心UI组件,用于相册选图/视频)PickerController, // 选择器控制器(用于控制选择器的显示、隐藏、回调等)PickerOptions, // 选择器配置项(配置选择模式、可选类型、最大数量等)DataType, // 数据类型枚举(指定选择的媒体类型:图片/视频/音频等)BaseItemInfo, // 基础媒体项信息(媒体文件的通用属性基类)ItemInfo, // 媒体项详情(继承BaseItemInfo,包含更具体的媒体属性)PhotoBrowserInfo, // 照片浏览器信息(用于预览媒体时的配置参数)ItemType, // 媒体项类型枚举(区分单张图片/视频/相册文件夹等)ClickType, // 点击类型枚举(标识用户点击行为:选中/取消/预览等)MaxCountType, // 最大选择数类型枚举(限制选择媒体的数量规则)PhotoBrowserRange, // 照片浏览器范围枚举(预览时的媒体集合范围)ReminderMode, // 权限提醒模式枚举(权限申请时的弹窗提示策略)photoAccessHelper // 照片访问辅助工具(用于申请媒体权限、获取媒体文件等)
} from '@kit.MediaLibraryKit'; // 媒体库工具包(HarmonyOS系统提供的媒体操作核心库)iaLibraryKit';
以上导入的方法根据用户需求自行选择,不需要全部导入
第二步:创建Picker组件实例和控制实例
// 组件初始化时设置参数信息。pickerOptions: PickerOptions = new PickerOptions();// 组件初始化完成后,可控制组件部分行为。@State pickerController: PickerController = new PickerController();// 已选择的图片。@State selectUris: Array<string> = new Array<string>();// 目前选择的图片。@State currentUri: string = '';// 是否显示大图。@State isBrowserShow: boolean = false;
第三步:设置PickerOptions参数
// 设置picker宫格页数据类型。
this.pickerOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE // 图片和照片都显示。
// 最大选择数量。
this.pickerOptions.maxSelectNumber = 5;
// 超出最大选择数量时。
this.pickerOptions.maxSelectedReminderMode = ReminderMode.TOAST;
// 是否展示搜索框,默认false。
this.pickerOptions.isSearchSupported = true;
// 是否支持拍照,默认false。
this.pickerOptions.isPhotoTakingSupported = true;
第四步:选择图片时及选择图片后的操作回调
// 资源被选中回调,返回资源的信息,以及选中方式。
private onItemClicked(itemInfo: ItemInfo, clickType: ClickType): boolean {if (!itemInfo) {return false;}let type: ItemType | undefined = itemInfo.itemType;let uri: string | undefined = itemInfo.uri;if (type === ItemType.CAMERA) {// 点击相机item。return true; // 返回true则拉起系统相机,若应用需要自行处理则返回false。} else {if (clickType === ClickType.SELECTED) {// 应用做自己的业务处理。if (uri) {this.selectUris.push(uri);this.pickerOptions.preselectedUris = [...this.selectUris];}return true; // 返回true则勾选,否则则不响应勾选。} else {if (uri) {this.selectUris = this.selectUris.filter((item: string) => {return item != uri;});this.pickerOptions.preselectedUris = [...this.selectUris];}}return true;}
}// 进入大图的回调。
private onEnterPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {this.isBrowserShow = true;return true;
}// 退出大图的回调。
private onExitPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {this.isBrowserShow = false;return true;
}// 接收到该回调后,便可通过pickerController相关接口向picker发送数据,在此之前不生效。
private onPickerControllerReady(): void {let elements: number[] = [PhotoBrowserUIElement.BACK_BUTTON];this.pickerController.setPhotoBrowserUIElementVisibility(elements, false); // 设置大图页不显示返回按钮。
}// 大图左右滑动的回调。
private onPhotoBrowserChanged(browserItemInfo: BaseItemInfo): boolean {this.currentUri = browserItemInfo.uri ?? '';return true;
}// 已勾选图片被删除时的回调。
private onSelectedItemsDeleted(baseItemInfos: Array<BaseItemInfo>): void {
}// 超过最大选择数量再次点击时的回调。
private onExceedMaxSelected(exceedMaxCountType: MaxCountType): void {
}// 当前相册被删除时的回调。
private onCurrentAlbumDeleted(): void {
}
第五步:创建调用组件,可以使用组件调用,也可以直接用代码唤起
PhotoPickerComponent({pickerOptions: this.pickerOptions,onItemClicked: (itemInfo: ItemInfo, clickType: ClickType): boolean => this.onItemClicked(itemInfo, clickType),onEnterPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onEnterPhotoBrowser(photoBrowserInfo),onExitPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onExitPhotoBrowser(photoBrowserInfo),onPickerControllerReady: (): void => this.onPickerControllerReady(),onPhotoBrowserChanged: (browserItemInfo: BaseItemInfo): boolean => this.onPhotoBrowserChanged(browserItemInfo),onSelectedItemsDeleted: (BaseItemInfo: Array<BaseItemInfo>) => this.onSelectedItemsDeleted(BaseItemInfo),onExceedMaxSelected: (exceedMaxCountType: MaxCountType) => this.onExceedMaxSelected(exceedMaxCountType),onCurrentAlbumDeleted: () => this.onCurrentAlbumDeleted(),pickerController: this.pickerController,})
至此整个图片操作的过程和步骤就全部结束了,开发者可以根据自己的需求,对其中的功能进行增减,以下为完整的代码示例,可直接复制使用
import {PhotoPickerComponent,PickerController,PickerOptions,DataType,BaseItemInfo,ItemInfo,PhotoBrowserInfo,ItemType,ClickType,MaxCountType,PhotoBrowserRange,ReminderMode,photoAccessHelper
} from '@kit.MediaLibraryKit';@Entry
@Component
struct PhotoPickerComponentDemo {// 组件初始化时设置参数信息。pickerOptions: PickerOptions = new PickerOptions();// 组件初始化完成后,可控制组件部分行为。@State pickerController: PickerController = new PickerController();// 已选择的图片。@State selectUris: Array<string> = new Array<string>();// 目前选择的图片。@State currentUri: string = '';// 是否显示大图。@State isBrowserShow: boolean = false;aboutToAppear() {// 设置picker宫格页数据类型this.pickerOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE // 图片和照片都显示。// 最大选择数量。this.pickerOptions.maxSelectNumber = 5;// 超出最大选择数量时。this.pickerOptions.maxSelectedReminderMode = ReminderMode.TOAST;// 是否展示搜索框,默认false。this.pickerOptions.isSearchSupported = true;// 是否支持拍照,默认false。this.pickerOptions.isPhotoTakingSupported = true;}// 资源被选中回调,返回资源的信息,以及选中方式。private onItemClicked(itemInfo: ItemInfo, clickType: ClickType): boolean {if (!itemInfo) {return false;}let type: ItemType | undefined = itemInfo.itemType;let uri: string | undefined = itemInfo.uri;if (type === ItemType.CAMERA) {// 点击相机item。return true; // 返回true则拉起系统相机,若应用需要自行处理则返回false。} else {if (clickType === ClickType.SELECTED) {// 应用做自己的业务处理。if (uri) {this.selectUris.push(uri);this.pickerOptions.preselectedUris = [...this.selectUris];}return true; // 返回true则勾选,否则则不响应勾选。} else {if (uri) {this.selectUris = this.selectUris.filter((item: string) => {return item != uri;});this.pickerOptions.preselectedUris = [...this.selectUris];}}return true;}}// 进入大图的回调。private onEnterPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {this.isBrowserShow = true;return true;}// 退出大图的回调。private onExitPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {this.isBrowserShow = false;return true;}// 接收到该回调后,便可通过pickerController相关接口向picker发送数据,在此之前不生效。private onPickerControllerReady(): void {}// 大图左右滑动的回调。private onPhotoBrowserChanged(browserItemInfo: BaseItemInfo): boolean {this.currentUri = browserItemInfo.uri ?? '';return true;}// 已勾选图片被删除时的回调。private onSelectedItemsDeleted(baseItemInfos: Array<BaseItemInfo>): void {}// 超过最大选择数量再次点击时的回调。private onExceedMaxSelected(exceedMaxCountType: MaxCountType): void {}// 当前相册被删除时的回调。private onCurrentAlbumDeleted(): void {}build() {Flex({direction: FlexDirection.Column,alignItems: ItemAlign.Start}) {PhotoPickerComponent({pickerOptions: this.pickerOptions,onItemClicked: (itemInfo: ItemInfo, clickType: ClickType): boolean => this.onItemClicked(itemInfo, clickType),onEnterPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onEnterPhotoBrowser(photoBrowserInfo),onExitPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onExitPhotoBrowser(photoBrowserInfo),onPickerControllerReady: (): void => this.onPickerControllerReady(),onPhotoBrowserChanged: (browserItemInfo: BaseItemInfo): boolean => this.onPhotoBrowserChanged(browserItemInfo),onSelectedItemsDeleted: (BaseItemInfo: Array<BaseItemInfo>) => this.onSelectedItemsDeleted(BaseItemInfo),onExceedMaxSelected: (exceedMaxCountType: MaxCountType) => this.onExceedMaxSelected(exceedMaxCountType),onCurrentAlbumDeleted: () => this.onCurrentAlbumDeleted(),pickerController: this.pickerController,})// 这里模拟应用侧底部的选择栏。if (this.isBrowserShow) {// 已选择的图片缩略图。Row() {ForEach(this.selectUris, (uri: string) => {if (uri === this.currentUri) {Image(uri).height(50).width(50).onClick(() => {}).borderWidth(1).borderColor('red')} else {Image(uri).height(50).width(50).onClick(() => {this.pickerController.setData(DataType.SET_SELECTED_URIS, this.selectUris);this.pickerController.setPhotoBrowserItem(uri, PhotoBrowserRange.ALL);})}}, (uri: string) => JSON.stringify(uri))}.alignSelf(ItemAlign.Center).margin(this.selectUris.length ? 10 : 0)} else {// 进入大图,预览已选择的图片。Button('预览').width('33%').alignSelf(ItemAlign.Start).height('5%').margin(10).onClick(() => {if (this.selectUris.length > 0) {this.pickerController.setPhotoBrowserItem(this.selectUris[0], PhotoBrowserRange.SELECTED_ONLY);}})}}}
}
欢迎大家跟我一起学习鸿蒙开发知识,加入我的班级,参与HarmonyOS赋能资源丰富度建设(第四期),获得HarmonyOS应用开发者认证 每月对前200名学员进行激励,活动期间共计激励1000名
华为开发者学堂
