android.permission.READ_EXTERNAL_STORAGE 权限永久拒绝,手动打开应用设权限置无效
android.permission.READ_EXTERNAL_STORAGE 权限永久拒绝,手动打开应用设权限置无效
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
uniapp | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Mac
PC开发环境操作系统版本号:macOS Sonoma 14.3.1
HBuilderX类型:正式
HBuilderX版本号:4.45
手机系统:Android
手机系统版本号:Android 14
手机厂商:小米
手机机型:Redmin K60 Pro 澎湃OS 1.0.16.0
页面类型:vue
vue版本:vue2
打包方式:云端
示例代码:
// 安卓拨打电话权限
const androidPermissions = {
'android.permission.CAMERA': {
title: '相机权限使用说明',
content: '需要获取相机权限,以便拍照上传图片',
},
'android.permission.READ_EXTERNAL_STORAGE': {
title: '存储空间/照片权限申请说明',
content: '需要获取访问设备上的照片、文件权限, 以便选择图片', // 存储读取权限
},
'android.permission.CALL_PHONE': {
title: '拨打电话权限申请说明',
content: '需要获取电话权限,以便拨打电话',
},
}
export function checkPermission(permissionIds: string[]): Promise<number> {
return new Promise((resolve, reject) => {
if (plus) {
const ids = permissionIds
plus.android.requestPermissions(
ids,
(resultObj) => {
let result = 0
let deniedPermissionInfo = ''
for (let i = 0; i < resultObj.granted.length; i++) {
const grantedPermission = resultObj.granted[i]
console.log('已获取的权限:' + grantedPermission)
result = 1
}
for (let i = 0; i < resultObj.deniedPresent.length; i++) {
const deniedPresentPermission = resultObj.deniedPresent[i]
console.log('拒绝本次申请的权限:' + deniedPresentPermission)
result = 0
}
for (let i = 0; i < resultObj.deniedAlways.length; i++) {
deniedPermissionInfo = resultObj.deniedAlways[i]
console.log('永久拒绝申请的权限:' + deniedPermissionInfo)
result = -1
}
if (result === -1) {
showPermissionDialog(deniedPermissionInfo)
}
resolve(result)
},
(error) => {
console.log('申请权限错误:' + error.code + ' = ' + error.message)
reject(error)
},
)
}
})
}
function showPermissionDialog(deniedPermissionInfo: string) {
const permissionInfo = androidPermissions[deniedPermissionInfo]
if (permissionInfo) {
uni.showModal({
title: permissionInfo.title,
content: permissionInfo.content,
showCancel: true,
confirmText: '打开应用设置',
success: (res) => {
if (res.confirm) {
gotoAppPermissionSetting()
}
},
})
}
}
function gotoAppPermissionSetting() {
const mainActivity = plus.android.runtimeMainActivity()
const Intent = plus.android.importClass('android.content.Intent')
const Settings = plus.android.importClass('android.provider.Settings')
const Uri = plus.android.importClass('android.net.Uri')
const intent = new Intent()
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
const uri = Uri.fromParts('package', mainActivity.getPackageName(), null)
intent.setData(uri)
mainActivity.startActivity(intent)
}
操作步骤:
第二次显示 点击永久拒绝,应用权限设置允许后,返回应用上传还是提示 去设置打开权限,日志显示 永久拒绝申请的权限:android.permission.READ_EXTERNAL_STORAGE
预期结果:
第二次显示 点击永久拒绝,应用权限设置允许后, 返回应用应该正常去上传图片,不显示打开权限
实际结果:
第二次显示 点击永久拒绝,应用权限设置允许后, 返回应用上传 日志还是显示 “永久拒绝申请的权限:android.permission.READ_EXTERNAL_STORAGE”
bug描述:
uniapp 打包安卓, android.permission.READ_EXTERNAL_STORAGE 权限校验第二次永久拒绝后,到应用设置中打开相册无效(权限如下图)
再次上传图片前校验 打印出来, 还是提示永久拒绝申请的权限:android.permission.READ_EXTERNAL_STORAGE
https://ask.dcloud.net.cn/question/197843
说是被废弃了
Android 33 以上设备
WRITE_EXTERNAL_STORAGE 权限已废弃。需要修改为
非常感谢
和我的问题一样,求解
这个问题是由于Android 14的权限管理机制变化导致的。在Android 14中,READ_EXTERNAL_STORAGE权限的行为有所调整,特别是当用户选择"永久拒绝"后。
解决方案是需要在每次检查权限前,先调用plus.android.requestPermissions
重新请求权限,即使之前被永久拒绝。这是因为:
- Android 14对存储权限管理更严格
- 用户手动开启权限后,应用需要重新触发权限请求流程
- 当前代码中只检查权限状态但没有重新请求
修改建议:
在checkPermission
函数中,当检测到deniedAlways
时,直接重新调用权限请求:
if (result === -1) {
showPermissionDialog(deniedPermissionInfo)
// 增加重新请求权限的逻辑
plus.android.requestPermissions(ids, /* 回调函数 */)
}