Android 10 申请动态权限以后仍然无法读写文件的解决方案
Posted 川峰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 10 申请动态权限以后仍然无法读写文件的解决方案相关的知识,希望对你有一定的参考价值。
如果 targetSdkVersion = 29
, 即便是在判断申请读写动态权限成功以后,也无法对外置卡路径(ExternalStorage)进行读写,可以使用以下代码进行测试
String path = Environment.getExternalStorageDirectory().getPath() + "/Download";
File file = new File(path);
if (file.exists()) {
if (file.canRead()) {
Log.e("AAA", "onCreate: file.canRead true");
} else {
Log.e("AAA", "onCreate: file.canRead false");
}
}
针对这个问题,以下是几种妥协的解决方法:
-
如应用非必须以 29 为target, 可以将
targetSdkVersion
置为 29 以下,如targetSdkVersion = 28
,这样走动态权限就正常了。 -
仍然以
targetSdkVersion
为 29,但是可在androidManifest.xml中application
标签添加android:requestLegacyExternalStorage="true"
,这样也可以,但是注意compileVersion
也必须同时为 29 :android { compileSdkVersion 29 buildToolsVersion "29.0.3" defaultConfig { applicationId "com.android.test.lib" minSdkVersion 19 targetSdkVersion 29 versionCode 1 versionName "1.0" } ... }
这种方案暂时有效,但是官方在未来的版本中可能去掉这个设置。
-
如果你是存文件,并且只是应用内自己访问,可以将文件存在私有目录下,可以使用
getExternalFilesDir
或getExternalCacheDir
等方法, 以下我列出了几种常用的私有目录文件访问方式获取到的对应路径:方法 获取的路径 getExternalFilesDir(null) 根目录下的 Android / data / [your_packageName] / files getExternalCacheDir() 根目录下的 Android / data / [your_packageName] / files / cache getExternalMediaDirs() 根目录下的 Android / media / [your_packageName] getFilesDir() / data / user / 0 / [your_packageName] / files getCacheDir() / data / user / 0 / [your_packageName] / cache openFileOutput(“aaa.txt”, Context.MODE_PRIVATE) data / data / [your_packageName] / files / aaa.txt 其中,getExternalFilesDir可以传一个名字,获取对应类型的文件夹:
// /storage/emulated/0/Android/data/[your_packageName]/files/Pictures File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); // /storage/emulated/0/Android/data/[your_packageName]/files/Documents File dir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); // /storage/emulated/0/Android/data/[your_packageName]/files/Movies File dir = getExternalFilesDir(Environment.DIRECTORY_MOVIES);
但是这种方法只能访问应用自己的应用目录,不能访问除此之外的其他公共目录,这种被称为
App-specific
目录。访问公共目录或其他APP的App-specific
目录,只能通过MediaStore、SAF、或者其他APP 提供的ContentProvider、FileProvider等访问。 -
使用
MediaStore
,也就是通过ContentResolver
去访问系统的多媒体数据库,获取对应的Uri进行后续的读写操作,拿到Uri后,可以进一步转成输入流进行转储等。但是这种只针对多媒体类型的文件(图片、视频、音频),如果是其他普通的文件就不行了。 -
使用 SAF ,这种是Google官方提供的方法来访问存储卡上的其他文件的方法,看了一下,这个大概是一个文件选择器,启动之后让用户去选择特定的文件或文件夹,最终回调的结果也是Uri,拿到Uri后再进行读写删操作。
另外,需要注意的一点是,如果你的应用已经有线上版本,targetSdkVersion 升级一定慎重,因为targetSdkVersion 只能升级不能降级(降级会导致应用无法安装)。
更多关于Android 10 文件读写适配的指导可以参考:
Android 10 适配攻略小结
Android Q版本应用兼容性适配指导
以上是关于Android 10 申请动态权限以后仍然无法读写文件的解决方案的主要内容,如果未能解决你的问题,请参考以下文章
Android 10 申请动态权限以后仍然无法读写文件的解决方案