HarmonyOS 相册选图需要申请读权限吗?5 行代码告诉你答案:不需要
2026/9/20 8:43:42 网站建设 项目流程

前言

前两天写一个一篇从相册选择照片,进行识别的内容,今天有看到一个问题地址如下不在赘述了,本篇就针对这个问题详细的讲解一下 https://developer.huawei.com/consumer/cn/forum/topic/0208222707637089600?fid=0109140870620153026
“从相册选一张图片,要不要申请ohos.permission.READ_IMAGEVIDEO权限?”
说实话我一开始也拿不准。毕竟在 Android 里,读相册就得要权限,惯性思维嘛。后来翻文档跑了几个 demo 才搞明白:用 PhotoViewPicker 选图,完全不需要任何权限。但如果你直接用photoAccessHelper.getAssets()读媒体库,那就得申请,而且这个权限还是受限的,上架审核卡得很严。
这篇文章把两种方式的区别和完整实现都写清楚,跟着做就能跑起来。

先说结论

方式是否需要权限适用场景
PhotoViewPicker.select()不需要让用户主动从相册选图片/视频
photoAccessHelper.getAssets()需要READ_IMAGEVIDEO(受限权限)应用自己遍历读取媒体库

划重点:只要场景是"用户主动选图",就用 PhotoViewPicker,零权限,零审核风险。

效果如图

PhotoViewPicker 是什么

PhotoViewPicker 是 HarmonyOS 提供的系统图库选择器。调用它的select()方法后,系统会拉起图库界面,用户自己挑图片,选完之后把 URI 返回给你。

整个过程用户是主动参与的选择操作,不是应用在后台偷偷读取,所以系统认为不需要权限。

说白了就是:用户亲手给你的,不算偷。

完整实现:从相册选一张图并回显

导入依赖

只有两个:picker用来选图,BusinessError用来捕获异常。

import{picker}from'@kit.CoreFileKit'import{BusinessError}from'@kit.BasicServicesKit'

注意picker来自@kit.CoreFileKit,不是@kit.MediaLibraryKit,这个搞错了编译都过不了。

选图方法

核心逻辑就这几行:

privateasyncpickImage():Promise<void>{constoptions:picker.PhotoSelectOptions=newpicker.PhotoSelectOptions()options.MIMEType=picker.PhotoViewMIMETypes.IMAGE_TYPEoptions.maxSelectNumber=1constphotoPicker:picker.PhotoViewPicker=newpicker.PhotoViewPicker()try{constresult:picker.PhotoSelectResult=awaitphotoPicker.select(options)if(result.photoUris.length>0){this.selectedUri=result.photoUris[0]}}catch(e){consterr:BusinessError=easBusinessErrorconsole.error(`pickImage failed:${err.code}`)}}

逐行解释:

  1. PhotoSelectOptions是选图配置。MIMEType设为IMAGE_TYPE表示只选图片,不选视频。maxSelectNumber设为 1 表示只选一张。
  2. PhotoViewPicker是选择器实例,调用select()拉起系统图库。
  3. 返回的PhotoSelectResult里有photoUris数组,就是用户选中的图片 URI。
  4. 拿到 URI 后赋值给@State变量,UI 自动刷新显示图片。

页面布局

选完图在页面上显示出来,同时放一个按钮触发选图:

@Entry@Componentstruct Qa8{@StateselectedUri:string=''// pickImage 方法同上,省略build(){Column(){if(this.selectedUri.length>0){Image(this.selectedUri).width(300).height(300).objectFit(ImageFit.Contain).borderRadius(8).margin({bottom:24})}Button('从相册选择图片').type(ButtonType.Capsule).backgroundColor('#3274F6').fontColor(Color.White).width('60%').onClick(()=>{this.pickImage()})}.width('100%').height('100%').justifyContent(FlexAlign.Center).backgroundColor('#FFFFFF')}}

几个细节:

  • Image组件可以直接用 PhotoViewPicker 返回的 URI 加载图片,不需要额外转换。
  • objectFit(ImageFit.Contain)保证图片等比缩放不裁剪。
  • if (this.selectedUri.length > 0)判断是否显示图片,选图前不显示。

完整代码

把上面的部分合在一起,完整代码如下:

import{picker}from'@kit.CoreFileKit'import{BusinessError}from'@kit.BasicServicesKit'@Entry@Componentstruct Qa8{@StateselectedUri:string=''privateasyncpickImage():Promise<void>{constoptions:picker.PhotoSelectOptions=newpicker.PhotoSelectOptions()options.MIMEType=picker.PhotoViewMIMETypes.IMAGE_TYPEoptions.maxSelectNumber=1constphotoPicker:picker.PhotoViewPicker=newpicker.PhotoViewPicker()try{constresult:picker.PhotoSelectResult=awaitphotoPicker.select(options)if(result.photoUris.length>0){this.selectedUri=result.photoUris[0]}}catch(e){consterr:BusinessError=easBusinessErrorconsole.error(`pickImage failed:${err.code}`)}}build(){Column(){if(this.selectedUri.length>0){Image(this.selectedUri).width(300).height(300).objectFit(ImageFit.Contain).borderRadius(8).margin({bottom:24})}Button('从相册选择图片').type(ButtonType.Capsule).backgroundColor('#3274F6').fontColor(Color.White).width('60%').onClick(()=>{this.pickImage()})}.width('100%').height('100%').justifyContent(FlexAlign.Center).backgroundColor('#FFFFFF')}}

不需要在module.json5里声明任何权限,直接跑就行。

什么时候才需要 READ_IMAGEVIDEO

只有一个场景:你的应用需要在不经过用户选择的情况下,直接读取媒体库中的图片或视频。

比如:

  • 换机克隆:把旧手机的所有照片复制到新手机
  • 云端备份:自动把本地照片上传到云端
  • 跨设备同步:在设备间同步媒体文件

这些场景下,应用无法通过 PhotoViewPicker 让用户一张张选,必须直接访问媒体库,这才需要READ_IMAGEVIDEO

其他所有"用户主动选图"的场景,PhotoViewPicker 都是最佳方案——零权限、实现简单、用户体验好。

写在最后

这个知识点不难,但很多人(包括之前的我)容易在权限问题上纠结半天。核心就一句话:用户选的不要权限,你偷读的才要权限。
如果你在做头像上传、朋友圈发图这类功能,直接用 PhotoViewPicker,别多想。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询