开发环境
- 框架: uniapp-x
- 版本: vue3
- 系统: Android
- 打包方式: 离线包(可能云打包没有这类问题)
- 打包工具: Hbuilder 4.29 (最新版本)
场景
uniapp官方提供了本地选择图片的Api uni.chooseImage
,APP中,需要用户手动选择相册/相机中上传图片,再进行后续操作...
在Android 版本 >= 13 时,会出现没有系统授权弹框,而默认认为拒绝授权的情况,用户无法进入相册选择本地图片。
真机预览
呈现结果
<无法访问图库>是程序内自定义的弹框,不要感到奇怪,后续会分析代码
预期结果
分析代码
- 找到调用相册/相机方法入口
onAddImage
// 检查相册/相机权限
if (type === 'album') {
if (!await Permissions.requestAlbumPermission()) {
return
}
} else if (type === 'camera') {
if (!await Permissions.requestCameraPermission()) {
return
}
}
App.feedTap() // 震动提示
let path
try {
// 封装的 uni.chooseImage 方法
path = await App.chooseImage([type])
} catch (e) {
// 忽略
console.error(e)
return
}
// 安静的忽略
if (!path) {
return
}
// 上传图片
const progress = (uploadTask, uploadProgress) => {
App.updateLoading({
progress: uploadProgress?.progress || 0,
})
}
App.showLoading({title: $t('work.uploading')})
try {
const userImage = await $work.uploadUserImage({path, progress})
onChooseImage(userImage)
// emits('close')
} catch (e) {
App.showError(e)
} finally {
App.hideLoading()
}
- 重点看
Permissions
这个类的静态方法requestAlbumPermission
- 根据
Platform.os.IOS
系统来区别 操作系统
- 最后触发校验弹框的方法是在
PermissionsAndroid
类的#requestPermission
实例 - 通过
plus.android.requestPermissions
检验,用Promise
返回结果 Messages.confirmAppSettings({perm})
是封装的通用提示框openAppAuthorizeSetting()
是封装的打开应用设置页面
核心代码
static requestAlbumPermission() {
return this.#requestPermission(
['android.permission.READ_EXTERNAL_STORAGE'],
$t('permission.album'),
)
}
- 当用户点击相册时,会验证
android.permission.READ_EXTERNAL_STORAGE
这条权限
改动
查阅了很久的文档,请教了公司安卓工作经验比较充足的前辈得知:
Android 13 之后,访问特定文件类型需要更细分的权限:
- 读取图片:
android.permission.READ_MEDIA_IMAGES
- 读取视频:
android.permission.READ_MEDIA_VIDEO
- 读取音频:
android.permission.READ_MEDIA_AUDIO
android.permission.READ_EXTERNAL_STORAGE
这条权限不支持了,我们需要根据android版本去请求不同的权限
static requestAlbumPermission() {
if(Platform.os.VERSION_MAJOR >= 13){
return this.#requestPermission(
['android.permission.READ_MEDIA_IMAGES'],
$t('permission.album'),
)
}else{
return this.#requestPermission(
['android.permission.READ_EXTERNAL_STORAGE'],
$t('permission.album'),
)
}
}
类似
和读取权限类似,app内还有一个保存图片到相册的功能,在 Android13 也做了升级。
READ_EXTERNAL_STORAGE
和 WRITE_EXTERNAL_STORAGE
权限,在 Android 13 中不再推荐这种方式,且逐步失效。
- Android 13 以上的方式
- 使用应用专属目录(无需权限)