精准打击工具类产品。
获取手机外部存储的根目录,一般通过这种方式,
1 | val externalRoot = Environment.getExternalStorageDirectory() |
返回的目录的绝对路径一般是,
1 | /storage/emulated/0/ |
也可以使用/sdcard/
代替,二者指向同一目录,映射关系如下,在一些特殊设备上可能会有不同,
1 | sdcard -> /storage/self/primary |
当在externalRoot
上调用listFiles()
方法,如果返回为空,需要检查以下两点:
- 请求读取权限
是否已经获取READ_EXTERNAL_STORAGE
权限,如果没有则返回null - 使用旧存储模型Android 10(target29)及更高版本推出了一种新的存储范例,叫做分区存储,直白一点讲,就是进一步收紧了访问权限,只可访问应用专属的目录,和几个特定的公开目录,如图片文件、下载文件,等,其他的均不可以访问,所以
1
2
3<application
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true" />listFiles()
会返回null,因为没有权限。
在Android 10上,将requestLegacyExternalStorage
设置为true,可以照常使用旧存储模型。
在Android 11上,将preserveLegacyExternalStorage
设置为true,只有覆盖安装的应用可以最后挣扎一下,照常使用旧存储模型,如果是新安装的,则是一点机会也没有。
参考
- 一文带你了解适配Android 11分区存储
- Android 11 中的存储机制更新