android 10 适配 沙盒 获取根目录权限以及适配过程中的坑

首先还是要丢一下官方适配连接,刚开始准备适配的朋友还是去官网玩耍一波:
https://developer.android.google.cn/about/versions/10


先说下我的需求适配android 10沙盒,需要获取到根目录权限,能够自由的去操控存储。
当去看完官方android 10的文档说明时,并没有发现适配根目录的方案,坑爹吧,怎么下手啊
没辙继续看官方说明的,然后找到下面连接,去github下载Demo测试
https://developer.android.google.cn/training/data-storage/files/media#manage-groups-of-files
测试跳转也只能跳转到下载位置,需要手动切换显示隐藏文件的时候可以允许手机文件权限:


好吧,继续在搜素没有发现另外可行方案,官网也是只是说明了一下变更,并没有适配方案出来,发现华为官网适配也是需要引导用户手动授权,好咯,只能先如此了。


下面也放一下跳转代码以及回调返回的Uri

 

  private static final int READ_REQUEST_CODE = 42;

  Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
  intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
  Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
  startActivityForResult(intent, READ_REQUEST_CODE);



    @Override
    public void onActivityResult(int requestCode, int resultCode,Intent resultData) {
        //使用resultdata.getdata ( )提取该URI
        if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            Uri uri = null;
            if (resultData != null) {
                uri = resultData.getData();
          }
        }
    }


如此就可以获取到根目录的Uri了,下面你可以在你的根目录上为所欲为了...
下面继续说一下适配过程中的坑:

第一个坑:    一个是通过上面获取到根目录Uri的时候去循环根目录寻找文件时,是通过DocumentFile.fromTreeUri(Context,uri).listFiles();当循环拿到子目录的根据子目录Uri去获取子目录文件的时候,神奇的事情就发生了,拿到的目录还是根目录下的子目录 what?什么鬼?断点日志确定不是子目录Uri路径错误的时候,有的玩了...大条了,现在获取文件不能通过File file = new File(path);拿到路径那么该如何获取?

还是一句话继续走,拿起你的小手继续百度走起,查到google官网对DocumentFile一个说明引起了我的注意,连接如下https://developer.android.google.cn/jetpack/androidx/releases/documentfile?hl=zh-cn

什么鬼?androidx?bug修复?还有一个androidx包的引用?回到项目查看发现,项目引用的DocumentFile是V4包里面的,不会吧google官方的bug还推荐我们使用?那就只能测试一下androidx咯,项目引用替换成androidx发现还是不行,然后继续回到之前说明的bug部分,新的androidx下的DocumentFile引用包修复是1.0.1版本,好吧继续引用一下1.0.1版本测试,果然。可行

厉害了,我的哥。这尼玛我项目是不能转成androidx包引用的,老难题啊,继续深入,想对比一下V4包下面DocumentFile的源码和androidx 1.0.1的源码对比一下,发现比较难找V4下的源码,就直接拿androidx代码到项目替换了V4源码,测试了一波,可行。继续搬...
下面也贴一下androidx下DocumentFile源码的下载地址:

https://download.csdn.net/download/Rookie_or_beginner/12084721


第二个坑: 沙盒设配本来呢,只需要判断api是否小于29,就可以区分是否适配分区的,但是google官方硬是弄了一个requestLegacyExternalStorage暂停沙盒分区使用旧分区的东西出来,那样子单单判断api是否小于29已经不能满足条件了,清单文件里面暂时停用沙盒分区 requestLegacyExternalStorage =true,好吧,适配的时候判Environment.isExternalStorageLegacy()通过返回状态确定是否开启沙盒分区,然后我测试了无论清单文件requestLegacyExternalStorage是设置了true或者是false,乃至删除了requestLegacyExternalStorage属性,都是返回false,我擦,又是坑爹啊,难道google推荐的东西都是坑爹么?继续搜索资料找到一篇博客 连接:https://www.jianshu.com/p/418180d7e195

说apk安装时,会根据requestLegacyExternalStorage 属性来同事storage权限变化,我擦,脑子一闪,又是一个坑啊,apk安装的时候就进行权限处理,我擦果断卸载app,重装测试一波果然可以了,代码如下:

   public static boolean currenVersionLessThan29(){
        boolean flag = true;
        //如果本身是大于等于 29  并且开启沙盒 则返回false 走适配沙盒分支
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q  &&     
        !isExternalStorageLegacy()) {
            flag = false;
        }
        return flag;
    }

    /**
     * @return
     */
    private static boolean isExternalStorageLegacy(){
        return Environment.isExternalStorageLegacy();
    }

 

测试了清单文件添加了没有添加requestLegacyExternalStorage  属性前 Environment.isExternalStorageLegacy()方法获取出来的是false, 添加了requestLegacyExternalStorage = true 之后Environment.isExternalStorageLegacy()获取出来的是true,证明是可以的。但是不能添加之后在删除requestLegacyExternalStorage = true属性,因为Environment.isExternalStorageLegacy()获取出来还是true。

 

最后还是要感谢写我同事大佬聪,此间适配可是主力军,哈哈。希望能帮助到后面来排队挖坑的朋友哈

 

你可能感兴趣的:(android)