oynix

于无声处听惊雷,于无色处见繁花

File.listFiles()返回null的问题

精准打击工具类产品。

获取手机外部存储的根目录,一般通过这种方式,

1
val externalRoot = Environment.getExternalStorageDirectory()

返回的目录的绝对路径一般是,

1
/storage/emulated/0/

也可以使用/sdcard/代替,二者指向同一目录,映射关系如下,在一些特殊设备上可能会有不同,

1
2
3
sdcard -> /storage/self/primary
/storage/self/primary -> /mnt/user/0/primary
/mnt/user/0/primary -> /storage/emulated/0

当在externalRoot上调用listFiles()方法,如果返回为空,需要检查以下两点:

  • 请求读取权限
    是否已经获取READ_EXTERNAL_STORAGE权限,如果没有则返回null
  • 使用旧存储模型
    1
    2
    3
    <application
    android:preserveLegacyExternalStorage="true"
    android:requestLegacyExternalStorage="true" />
    Android 10(target29)及更高版本推出了一种新的存储范例,叫做分区存储,直白一点讲,就是进一步收紧了访问权限,只可访问应用专属的目录,和几个特定的公开目录,如图片文件、下载文件,等,其他的均不可以访问,所以listFiles()会返回null,因为没有权限。

在Android 10上,将requestLegacyExternalStorage设置为true,可以照常使用旧存储模型。

在Android 11上,将preserveLegacyExternalStorage设置为true,只有覆盖安装的应用可以最后挣扎一下,照常使用旧存储模型,如果是新安装的,则是一点机会也没有。

参考

  • 一文带你了解适配Android 11分区存储
  • Android 11 中的存储机制更新
------------- (完) -------------
  • 本文作者: oynix
  • 本文链接: https://oynix.com/2022/08/07d52a8ad8ea/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

欢迎关注我的其它发布渠道