HarmonyOS鸿蒙Next中如何进入应用通过同意权限直接获取全部相册,不想要通过picker页面手动获取全部图片

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

cke_232.png

【问题现象】:现在每次打开应用都需要通过picker页面手动获取全部图片,影响用户体验,如果只能使用这个组件, 那么就是每次启动app,都需要弹出这个页面,然后用户主动把所有图片都选择完,我才能帮助用户归类整理图片,有没有什么方法能直接选择获取全部相册的

【版本信息】:NA

【复现代码】:NA

【尝试解决方案】:NA


更多关于HarmonyOS鸿蒙Next中如何进入应用通过同意权限直接获取全部相册,不想要通过picker页面手动获取全部图片的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

开发者您好,请先自己配置权限申请相册读取权限ohos.permission.READ_IMAGEVIDEO,具体参考申请相册管理模块权限,用getAlbums方式试一下能不能满足条件,详情请参考1楼的答复,如果不能满足您的诉求,请及时反馈一下。

更多关于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模块来直接查询设备上的媒体文件。

关键步骤:

  1. 权限申请: 在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"
        }
      }
    ]
    

    在应用首次运行时,动态请求这些权限。

  2. 使用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。

这样,你的相册管理应用就可以在用户授权后,直接后台获取全部图片进行自动分类管理了。

回到顶部