HarmonyOS鸿蒙Next中如何进入应用通过同意权限直接获取全部相册,不想要通过picker页面手动获取全部图片
HarmonyOS鸿蒙Next中如何进入应用通过同意权限直接获取全部相册,不想要通过picker页面手动获取全部图片 【问题描述】:相册管理类的 app, 类似于 安卓或者 iOS 的相册管理, 希望用户打开 app,同意了权限,我就可以拿到所有图片进行分类整理,帮助用户管理图片,目前使用PhotoPicker

【问题现象】:现在每次打开应用都需要通过picker页面手动获取全部图片,影响用户体验,如果只能使用这个组件, 那么就是每次启动app,都需要弹出这个页面,然后用户主动把所有图片都选择完,我才能帮助用户归类整理图片,有没有什么方法能直接选择获取全部相册的
【版本信息】:NA
【复现代码】:NA
【尝试解决方案】:NA
更多关于HarmonyOS鸿蒙Next中如何进入应用通过同意权限直接获取全部相册,不想要通过picker页面手动获取全部图片的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,可以用PhotoAccessHelper获取全部相册试试,如果不行,麻烦您及时反馈:
【解决方案】
申请相册读取权限ohos.permission.READ_IMAGEVIDEO,具体参考申请相册管理模块权限;然后根据dataSharePredicates谓词查询,通过调用getAlbums接口获取全部相册图片对象PhotoAsset,根据displayName筛选。
完整示例如下:
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import { dataSharePredicates } from '@kit.ArkData';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
@Entry
@Component
struct SelectPhotoDemo {
private context = this.getUIContext().getHostContext() as Context as common.UIAbilityContext;
@State allPhotoAssets: Array<photoAccessHelper.PhotoAsset> = []; // 所有相册图片数组
@State resultPhotoAssets: Array<photoAccessHelper.PhotoAsset> = []; // 筛选的图片数组
aboutToAppear(): void {
// 申请相册读取权限
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
const permissions: Array<Permissions> = ['ohos.permission.READ_IMAGEVIDEO', "ohos.permission.WRITE_IMAGEVIDEO"];
atManager.requestPermissionsFromUser(this.context, permissions).then(async (data) => { //需要用户允许授权图库权限
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) { // 用户同意权限之后进行的操作
// ...
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
}).catch((err: BusinessError) => {
console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
});
}
// 获取相册所有图片
async getAllPhoto() {
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context);
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
const photoTitle = photoAccessHelper.PhotoKeys.TITLE;
let fetchOptions: photoAccessHelper.FetchOptions = {
fetchColumns: [photoTitle],
predicates: predicates
};
try {
// 获取系统相册中的图片相册
let albumFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> =
await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.SYSTEM, photoAccessHelper.AlbumSubtype.IMAGE);
let album: photoAccessHelper.Album = await albumFetchResult.getFirstObject();
let photoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> =
await album.getAssets(fetchOptions);
// 获取相册全部图片资源
let photoAssets = await photoFetchResult.getAllObjects();
this.allPhotoAssets = photoAssets;
photoFetchResult.close();
albumFetchResult.close();
} catch (err) {
console.error(`showPhotos failed, code is ${err.code}, message is ${err.message}`);
}
}
// 筛选相册中png格式的图片
async getPngPhoto() {
// 根据名称过滤
let showPhotos = this.allPhotoAssets.filter((photoAsset: photoAccessHelper.PhotoAsset) => {
const name = photoAsset.displayName;
// 根据名称中包含的字符串过滤,这里是示例过滤png的图片
return name.substring(name.indexOf('.') + 1) === 'png';
});
this.resultPhotoAssets = showPhotos;
}
build() {
Column({ space: 10 }) {
Button("获取相册所有图片")
.onClick(() => {
this.getAllPhoto();
})
if (this.allPhotoAssets.length > 0) {
Grid() {
ForEach(this.allPhotoAssets, (item: photoAccessHelper.PhotoAsset, index: number) => {
GridItem() {
Column({ space: 5 }) {
Image(item.uri)
.objectFit(ImageFit.Cover)
.width('100%')
.layoutWeight(1)
Text(item.displayName)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Center)
}
.margin({ left: 5, right: 5 })
}
.height(100)
})
}
.width('100%')
.height(300)
.columnsTemplate("1fr 1fr 1fr 1fr")
Button("筛选png格式的图片")
.onClick(() => {
this.getPngPhoto();
})
}
if (this.resultPhotoAssets.length > 0) {
Grid() {
ForEach(this.resultPhotoAssets, (item: photoAccessHelper.PhotoAsset, index: number) => {
GridItem() {
Column({ space: 5 }) {
Image(item.uri)
.objectFit(ImageFit.Cover)
.width('100%')
.layoutWeight(1)
Text(item.displayName)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Center)
}
.margin({ left: 5, right: 5 })
}
.height(100)
})
}
.width('100%')
.height(300)
.columnsTemplate("1fr 1fr 1fr 1fr")
}
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
}
}
【背景知识】
- PhotoAccessHelper:相册管理模块,提供getAlbums根据检索选项和相册类型获取相册,相册类型分为系统相册和用户相册。
- AbsAlbum:实体相册,通过PhotoAccessHelper获取到实体相册后,可以通过getAssets获取相册中的文件实例PhotoAsset。
在HarmonyOS Next中,应用可通过申请ohos.permission.READ_IMAGEVIDEO权限,并在module.json5中配置requestPermissions。用户同意授权后,应用即可直接访问全部相册,无需经过picker页面。
在HarmonyOS Next中,要实现应用在获得权限后直接访问全部相册,而不通过PhotoPicker界面手动选择,核心在于使用媒体库管理(MediaLibrary) 的相关API。
PhotoPicker是用于交互式选择的组件,不适合后台批量获取。你需要使用@ohos.file.mediaLibrary模块来直接查询设备上的媒体文件。
关键步骤:
-
权限申请: 在
module.json5文件中声明必要的权限:"requestPermissions": [ { "name": "ohos.permission.READ_IMAGEVIDEO", "reason": "$string:reason_desc", // 描述权限用途 "usedScene": { "abilities": [ "EntryAbility" ], "when": "always" } }, { "name": "ohos.permission.WRITE_IMAGEVIDEO", "reason": "$string:reason_desc", "usedScene": { "abilities": [ "EntryAbility" ], "when": "always" } } ]在应用首次运行时,动态请求这些权限。
-
使用MediaLibrary API查询所有图片: 获得权限后,你可以直接使用媒体库接口扫描设备,获取所有图片的元数据或URI。
示例代码(ArkTS):
import mediaLibrary from '@ohos.file.mediaLibrary'; import { BusinessError } from '@ohos.base'; async function getAllImages() { try { // 1. 获取媒体库实例 let media = mediaLibrary.getMediaLibrary(); // 2. 创建文件获取选项(FetchOptions) let fetchOptions: mediaLibrary.FetchOptions = { // 选择媒体类型:图片 selections: mediaLibrary.FileKey.MEDIA_TYPE + '=?', selectionArgs: [mediaLibrary.MediaType.IMAGE.toString()], // 可以添加排序规则,例如按修改时间倒序 order: mediaLibrary.FileKey.DATE_MODIFIED + ' DESC', }; // 3. 获取文件资源(FetchResult) let fetchResult: mediaLibrary.FetchResult = await media.getFileAssets(fetchOptions); // 4. 遍历结果,获取所有图片 let fileAssets: mediaLibrary.FileAsset[] = await fetchResult.getAllObject(); let imageUris: string[] = []; for (let fileAsset of fileAssets) { // 获取文件的URI,可用于后续显示或处理 imageUris.push(fileAsset.uri); // 你也可以通过 fileAsset 获取更多元数据,如路径、大小、时间等 // let title: string = fileAsset.title; // let size: number = fileAsset.size; } // 5. 释放FetchResult fetchResult.close(); console.log('成功获取所有图片URI列表:', imageUris); return imageUris; } catch (error) { let err: BusinessError = error as BusinessError; console.error('获取图片失败,错误码: ' + err.code + ', 错误信息: ' + err.message); } }
流程总结:
- 用户同意权限 → 应用调用
getAllImages()→ 直接获得设备内所有图片的URI列表。 - 你可以在应用启动时或权限授予后自动执行此查询,无需用户手动在Picker界面选择。
- 获得URI后,你可以使用
Image组件加载显示,或根据文件元信息(如日期、位置)进行分类整理。
注意事项:
- 性能:首次扫描大量图片可能需要一些时间,建议在后台异步执行,并考虑分页加载(
getFileAssets支持range参数)以避免界面卡顿。 - 隐私:确保应用有明确的相册管理功能说明,符合HarmonyOS的隐私规范。直接访问全部媒体文件属于敏感操作,权限说明必须清晰。
- API差异:HarmonyOS Next的媒体库API与Android/iOS有所不同,上述代码基于Next的ArkTS API。
这样,你的相册管理应用就可以在用户授权后,直接后台获取全部图片进行自动分类管理了。


