关于Android Q 的文件分区存储权限适配研究

Posted 陳英傑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Android Q 的文件分区存储权限适配研究相关的知识,希望对你有一定的参考价值。

我们发现每安装一个应用,你的手机文件管理中就会创建很多文件夹,而且应用卸载文件夹还在,里面的文件也在,手机用着用着文件系统越来越庞大,最后就是卡顿。
android 10 新特性中有一个保护外部存储设备中的用户数据,应用可以将自己的文件存储在专用沙盒中,另外就是可以访问公共文件夹,比如Download、DCIM、Music等,这样就不会在/storage/emulated/0/下面创建很多文件夹,你也不能随便访问别的应用文件夹。

  • Android 10
    虽然加入了此特性,但是Google肯定会考虑给开发者过渡期,Android 10 可以通过在manifest.xmlapplication标签下配置android:requestLegacyExternalStorage="true"来继续使用以前的存储方式,这只是一个临时解决方式,适配还是少不了的。
  • Android 11
    此后就要强制使用,即使添加android:requestLegacyExternalStorage="true",系统也会忽略的,官方文档有明确说明。

1、官方提供访问应用自己的目录方法

	/**
     * 获取本应用下的文件存储路径
     * 可直接写入文件
     *
     * @param context
     * @param type
     * @return /storage/emulated/0/Android/data/@package/files/@type
     */
    public static String getExternalFilesDir(Context context, String type) 
        File apk = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
            apk = context.getExternalFilesDir(type);
        return apk == null ? "" : apk.getAbsolutePath();
    

就是在文件管理中的 Android/data/ 目录下根据包名给应用创建各自的文件存储区,你可以在这个目录下存储文件,创建子目录(即type)。

2、获取公共区目录(Downloads、Documents、Pictures 、DCIM、Movies、Music、Ringtones),需要文件读写权限,除了这些目录外的都无法访问了。

	/**
     * 获取公共目录
     * 不能直接读/写文件,需要获取读写权限才能操作
     *
     * @param type Downloads、Documents、Pictures 、DCIM、Movies、Music、Ringtones
     * @param createDir 在type公共目录下创建新文件夹
     * @return
     */
    public static String getExternalStoragePublicDir(String type, String createDir) 
        File directory = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
            directory = Environment.getExternalStoragePublicDirectory(type);
        String path = directory == null ? "" : directory.getAbsolutePath();
        if (!TextUtils.isEmpty(createDir)) 
            path += File.separator + createDir;
            File file = new File(path);
            if (!file.exists()) file.mkdir();
            file = null;
        
        return path;
    

经测试,结果如下:

  • 小米10X Android10,不用开启requestLegacyExternalStorage,可以用以前的方式正常存储文件
  • 华为荣耀 Android10,需要开启requestLegacyExternalStorage,才可以用以前的方式存储文件,否则在存储文件的时候抛出FileNotFoundException异常。
  • 其他手机暂时没测试过。

以上是关于关于Android Q 的文件分区存储权限适配研究的主要内容,如果未能解决你的问题,请参考以下文章

Android Q R的适配-隐私权限

Android Q R的适配-隐私权限

Android Q R的适配-隐私权限

android Q sdcard权限详解

总结系列-Android10适配-分区存储

总结系列-Android10适配-分区存储