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截图

bug描述:

uniapp 打包安卓, android.permission.READ_EXTERNAL_STORAGE 权限校验第二次永久拒绝后,到应用设置中打开相册无效(权限如下图)

再次上传图片前校验 打印出来, 还是提示永久拒绝申请的权限:android.permission.READ_EXTERNAL_STORAGE


4 回复

https://ask.dcloud.net.cn/question/197843 说是被废弃了 Android 33 以上设备
WRITE_EXTERNAL_STORAGE 权限已废弃。需要修改为

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> "<uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\" />" "<uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\" />", "<uses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\" />",

非常感谢

和我的问题一样,求解

这个问题是由于Android 14的权限管理机制变化导致的。在Android 14中,READ_EXTERNAL_STORAGE权限的行为有所调整,特别是当用户选择"永久拒绝"后。

解决方案是需要在每次检查权限前,先调用plus.android.requestPermissions重新请求权限,即使之前被永久拒绝。这是因为:

  1. Android 14对存储权限管理更严格
  2. 用户手动开启权限后,应用需要重新触发权限请求流程
  3. 当前代码中只检查权限状态但没有重新请求

修改建议:

checkPermission函数中,当检测到deniedAlways时,直接重新调用权限请求:

if (result === -1) {
    showPermissionDialog(deniedPermissionInfo)
    // 增加重新请求权限的逻辑
    plus.android.requestPermissions(ids, /* 回调函数 */)
}
回到顶部