You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Java.lang.SecurityException: Permission Denial权限问题求解

解决方案:Android Content URI 权限持久化问题

问题核心

你遇到的SecurityException是因为通过ACTION_OPEN_DOCUMENT获取的content:// URI仅拥有临时权限,当应用重启或会话结束后权限会失效,普通的READ_EXTERNAL_STORAGE权限无法覆盖这类URI的访问权限。

可行解决步骤

1. 持久化URI访问权限

在获取图片URI的环节(即你完成第一步“从设备查找图片并添加到程序”的代码中),添加持久化权限的代码,确保后续重启应用后仍能访问该URI:

// 适配传统ActivityResult方式
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == YOUR_IMAGE_PICK_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
        Uri imageUri = data.getData();
        // 持久化读权限
        getContentResolver().takePersistableUriPermission(
            imageUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION
        );
        // 之后再将这个URI字符串保存到txt文件
    }
}

// 适配AndroidX ActivityResultContracts方式
ActivityResultLauncher<Intent> pickImageLauncher = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
            Uri imageUri = result.getData().getData();
            getContentResolver().takePersistableUriPermission(
                imageUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION
            );
            // 保存URI到txt文件
        }
    }
);

注意:必须使用ACTION_OPEN_DOCUMENT而非ACTION_GET_CONTENT来启动图片选择器,前者支持持久化权限,后者不支持。

2. 移除冗余权限

从AndroidManifest.xml中删除MANAGE_EXTERNAL_STORAGE权限,该权限用于全存储访问,不符合Scoped Storage规范,且会导致Google Play上架受阻,对你的场景完全无用:

<!-- 删除这一行 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage"/>

Android 13+版本下,READ_EXTERNAL_STORAGE也可以移除,因为通过ACTION_OPEN_DOCUMENT获取的URI权限无需该权限。

3. 优化图片加载代码

添加异常捕获避免崩溃,同时简化加载逻辑:

if (str_adress != null && !str_adress.isEmpty()) {
    try {
        Uri uri = Uri.parse(str_adress);
        imgg.setImageURI(uri);
    } catch (SecurityException e) {
        // 权限失效时的处理:比如提示用户重新选择图片
        Toast.makeText(getActivity(), "图片权限失效,请重新选择", Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
}

补充说明

  • content://类型的URI并非本地文件路径,不能直接用Drawable.createFromPath()加载,必须通过ContentResolver访问,setImageURI()内部会自动处理ContentResolver的调用。
  • 启动图片选择器时,需显式添加权限标记:
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    pickImageLauncher.launch(intent);
    

内容的提问来源于stack exchange,提问作者PewPew01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:15:44