Android 10 申请动态权限以后仍然无法读写文件的解决方案

160 阅读3分钟
  1. 如应用非必须以 29 为target, 可以将targetSdkVersion 置为 29 以下,如 targetSdkVersion = 28,这样走动态权限就正常了。

  2. 仍然以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"

}

...

}

这种方案暂时有效,但是官方在未来的版本中可能去掉这个设置。

  1. 如果你是存文件,并且只是应用内自己访问,可以将文件存在私有目录下,可以使用 getExternalFilesDirgetExternalCacheDir 等方法, 以下我列出了几种常用的私有目录文件访问方式获取到的对应路径:

| 方法 | 获取的路径 |

| :-- | :-- |

| 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等访问。

  1. 使用 MediaStore,也就是通过 ContentResolver去访问系统的多媒体数据库,获取对应的Uri进行后续的读写操作,拿到Uri后,可以进一步转成输入流进行转储等。但是这种只针对多媒体类型的文件(图片、视频、音频),如果是其他普通的文件就不行了。

  2. 使用 SAF ,这种是Google官方提供的方法来访问存储卡上的其他文件的方法,看了一下,这个大概是一个文件选择器,启动之后让用户去选择特定的文件或文件夹,最终回调的结果也是Uri,拿到Uri后再进行读写删操作。

另外,需要注意的一点是,如果你的应用已经有线上版本,targetSdkVersion 升级一定慎重,因为targetSdkVersion 只能升级不能降级(降级会导致应用无法安装)。

总结

最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

详细整理在GitHub可以见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

技术进阶之路很漫长,一起共勉吧~