
前言前两天写一个一篇从相册选择照片进行识别的内容今天有看到一个问题地址如下不在赘述了本篇就针对这个问题详细的讲解一下 https://developer.huawei.com/consumer/cn/forum/topic/0208222707637089600?fid0109140870620153026“从相册选一张图片要不要申请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}fromkit.CoreFileKitimport{BusinessError}fromkit.BasicServicesKit注意picker来自kit.CoreFileKit不是kit.MediaLibraryKit这个搞错了编译都过不了。选图方法核心逻辑就这几行privateasyncpickImage():Promisevoid{constoptions:picker.PhotoSelectOptionsnewpicker.PhotoSelectOptions()options.MIMETypepicker.PhotoViewMIMETypes.IMAGE_TYPEoptions.maxSelectNumber1constphotoPicker:picker.PhotoViewPickernewpicker.PhotoViewPicker()try{constresult:picker.PhotoSelectResultawaitphotoPicker.select(options)if(result.photoUris.length0){this.selectedUriresult.photoUris[0]}}catch(e){consterr:BusinessErroreasBusinessErrorconsole.error(pickImage failed:${err.code})}}逐行解释PhotoSelectOptions是选图配置。MIMEType设为IMAGE_TYPE表示只选图片不选视频。maxSelectNumber设为 1 表示只选一张。PhotoViewPicker是选择器实例调用select()拉起系统图库。返回的PhotoSelectResult里有photoUris数组就是用户选中的图片 URI。拿到 URI 后赋值给State变量UI 自动刷新显示图片。页面布局选完图在页面上显示出来同时放一个按钮触发选图EntryComponentstruct Qa8{StateselectedUri:string// pickImage 方法同上省略build(){Column(){if(this.selectedUri.length0){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}fromkit.CoreFileKitimport{BusinessError}fromkit.BasicServicesKitEntryComponentstruct Qa8{StateselectedUri:stringprivateasyncpickImage():Promisevoid{constoptions:picker.PhotoSelectOptionsnewpicker.PhotoSelectOptions()options.MIMETypepicker.PhotoViewMIMETypes.IMAGE_TYPEoptions.maxSelectNumber1constphotoPicker:picker.PhotoViewPickernewpicker.PhotoViewPicker()try{constresult:picker.PhotoSelectResultawaitphotoPicker.select(options)if(result.photoUris.length0){this.selectedUriresult.photoUris[0]}}catch(e){consterr:BusinessErroreasBusinessErrorconsole.error(pickImage failed:${err.code})}}build(){Column(){if(this.selectedUri.length0){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别多想。