Android 11 访问 Android/data/或者getExternalCacheDir() 非root方式

前言

需求要求安装三方应用ExternalCacheDir()下载下来的apk文件。

getExternalCacheDir() : /storage/emulated/0/Android/data/com../cache/

获取访问权限

如果手机安卓版本为Android10的时候,可以在AndroidManifest.xml中添加下列代码

复制代码
   android:requestLegacyExternalStorage="true"

以此禁用分区存储,但这在Android11及以上版本不起作用。

使用 Storage Access Framework 请求访问权限。

SAF 提供了一种标准化的方式来让应用程序请求访问其他应用的文件和目录。要使用 SAF 请求访问 Android/data 目录。

复制代码
	private static int REQUEST_CODE_FOR_DIR = 10525;

    //通过SAF获取权限
 	public  void startForSAF(Activity activity) {
        Uri uri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata");
        DocumentFile documentFile = DocumentFile.fromTreeUri(activity, uri);
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
        assert documentFile != null;
        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, documentFile.getUri());
        activity.startActivityForResult(intent, REQUEST_CODE_FOR_DIR);
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Uri uri;
        if (requestCode == REQUEST_CODE_FOR_DIR && (uri = data.getData()) != null) {
            getContentResolver().takePersistableUriPermission(uri, data.getFlags() & (
                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
            finish();
        }
    }

    //使用时
    public static Uri pathToUri(String path) {
        return Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3A" +path.replace("/storage/emulated/0/", "").replace("/", "%2F"));
    }

效果如下:

相关推荐
Kapaseker15 小时前
详解 Compose background 的重组陷阱
android·kotlin
黄林晴15 小时前
Kotlin 2.3.20-RC2 来了!JPA 开发者狂喜,6 大更新一文速览
android·kotlin
kymjs张涛1 天前
OpenClaw 学习小组:初识
android·linux·人工智能
范特西林1 天前
实战演练——从零实现一个高性能 Binder 服务
android
范特西林1 天前
代码的生成:AIDL 编译器与 Parcel 的序列化艺术
android
范特西林1 天前
深入内核:Binder 驱动的内存管理与事务调度
android
范特西林1 天前
解剖麻雀:Binder 通信的整体架构全景图
android
范特西林1 天前
破冰之旅:为什么 Android 选择了 Binder?
android
奔跑中的蜗牛6661 天前
一次播放器架构升级:Android 直播间 ANR 下降 60%
android
测试工坊2 天前
Android 视频播放卡顿检测——帧率之外的第二战场
android