Android数据存储之Android 6.0运行时权限下文件存储的思考

前言:

     在咱们作App开发的过程当中基本上都会用到文件存储,因此文件存储对于咱们来讲是至关熟悉了,不过自从Android 6.0发布以后,基于运行时权限机制访问外置sdcard是须要动态申请权限,因此以往直接sdcard根目录上直接新建了一个xxx/cache/目录来作文件存储就会不是那么容易控制了,因此有必要从新认识一下Android文件存储的相关知识了。android

背景:

   有关外置sdcard的读写权限算法

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

   在Android 6.0 以前只要申明了上述两个权限就能够放心大胆的在sdcard上进行读写了,惋惜Android 6.0以后就须要动态申请读写权限了,因此咱们该如何适配Android 6.0来进行文件存储。首先咱们在使用文件存储的时候尽可能作到如下几点:浏览器

  • 不要随意占用用户的内置存储缓存

  • 不要随意在SD卡上新建目录,应该放置本身应用包名对应的扩展存储目录下,卸载App时能够被自动清除。app

  • 对占用的磁盘空间有上限,并按照必定的策略进行清除,好比DiskLru算法等。学习

Android文件存储目录:

1.)应用私有存储(内置存储)

访问方式 详细路径 是否须要申请权限

Context.getFileDir();获取内置存储下的文件目录,能够用来保存不能公开给其余应用的一些敏感数据如用户我的信息spa

 /data/data/应用包名/files/  否

Context.getCacheDir();获取内置存储下的缓存目录,能够用来保存一些缓存文件如图片,当内置存储的空间不足时将系统自动被清除日志

 /data/data/应用包名/cache/ 否 

注意:code

 因为这里使用的是Android 手机内置存储,若是手机没有得到root权限的话文件浏览器是没法访问的,一样这种存储也会随之app被删除而被删除。orm

2.)应用扩展存储(SD卡)

访问方式 路径详情 是否须要申请权限

 Context.getExternalFilesDir();获取SD卡上的文件目录,

 SDCard/Android/data/应用包名/files/

 API < 19:是

API >= 19:否

 Context.getExternalCacheDir();获取SD卡上的缓存目录,能够用来保存一些缓存文件如图片

 SDCard/Android/data/应用包名/cache/

 API < 19:是

API >= 19:否

 注意:

   因为存储在sdcard上因此尽可能不要存在敏感数据好比用户信息等,这里的文件也会随着app 被删除而被删除。

3.)公共存储(SD卡)

访问方式 路径详情 是否须要申请权限
Environment.getExternalStorageDirectory();获取sdcard根目录 SDCard/xxx文件夹名字/

注意:

  有时咱们也是须要存储一些公共文件,并且但愿这些文件可以不随着App被删除而被删除,例如咱们录制的视频或者下载的音乐等。因为这个目录能够被任何app访问,因此咱们在使用的时候是须要申请权限的。

兼容Android 6.0 文件缓存实现

  前提:这里主要处理一些非永久保存数据,须要永久保存的数据尽可能仍是要选择sdcard 公共存储方式的。

1.)获取缓存根目录

  /**
     * 获取app的根目录
     *
     * @return 文件缓存根路径
     */
    public static String getDiskCacheRootDir() {
        File diskRootFile;
        if (existsSdcard()) {
            diskRootFile = LeeApplication.getApp().getExternalCacheDir();
        } else {
            diskRootFile = LeeApplication.getApp().getCacheDir();
        }
        String cachePath;
        if (diskRootFile != null) {
            cachePath = diskRootFile.getPath();
        } else {
            throw new IllegalArgumentException("disk is invalid");
        }
        return cachePath;
    }

这里须要判断sdcard是否可用

    /**
     * 判断外置sdcard是否能够正常使用
     *
     * @return
     */
    public static Boolean existsSdcard() {
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable();
    }

2.)获取指定功能的目录

  /**
     * 获取相关功能业务目录
     *
     * @return 文件缓存路径
     */
    public static String getDiskCacheDir(String dirName) {
        String dir = String.format("%s/%s/", getDiskCacheRootDir(), dirName);
        File file = new File(dir);
        if (!file.exists()) {
            boolean isSuccess = file.mkdirs();
            if (isSuccess) {
                Log.d(TAG, "dir mkdirs success");
            }
        }
        return file.getPath();
    }

在平常开发过程当中,咱们须要不一样的文件放在不一样的目录下,好比:log日志文件须要放在log文件下,就能够经过上面的方法传入“log”获取该业务功能的文件夹。

3.)获取指定功能文件路径

    /**
     * 获取log日志根目录
     * @return
     */
    public  static String getLogDir(){
        return getDiskCacheDir(LOG);
    }

    /**
     * 根据logName 获取log文件全路径
     * @param logName
     * @return
     */
    public  static String getLogFilePath(String logName){
        return  getLogDir()+logName;
    }

 总结:

      今天总结了Android的文件存储及在6.0上的适配问题,最近忽然以为本身有太多的知识须要学习了,也许因为如今的经济大环境致使互联网遇到了资本寒冬了,其实对于我来讲2012年已经经历过一次了,对于技术人员来讲应该冷静的看待这个问题,须要作的就是在寒冬里播种但愿,那就是学习。以此共勉之~

相关文章
相关标签/搜索