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


    前言:

         在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以往直接sdcard根目录上直接新建了一个xxx/cache/目录来做文件存储就会不是那么容易控制了,所以有必要重新认识一下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时可以被自动清除。

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

    Android文件存储目录:

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

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

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

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

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

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

    注意:

     由于这里使用的是Android 手机内置存储,如果手机没有获得root权限的话文件浏览器是无法访问的,同样这种存储也会随之app被删除而被删除。

    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年已经经历过一次了,对于技术人员来说应该冷静的看待这个问题,需要做的就是在寒冬里播种希望,那就是学习。以此共勉之~

  • 相关阅读:
    1104 Sum of Number Segments (20 分)(数学问题)
    1092 To Buy or Not to Buy (20 分)(hash散列)
    1082 Read Number in Chinese (25 分)(字符串处理)【背】
    1105 Spiral Matrix (25 分)(模拟)
    初识网络安全及搭建网站(内网)
    HTML5开发者需要了解的技巧和工具汇总(转)
    native+web开发模式之web前端经验分享
    移动平台3G手机网站前端开发布局技巧汇总(转)
    Asp.net 中图片存储数据库以及页面读取显示通用方法详解附源码下载
    使用H3Viewer来查看VS2010的帮助文档
  • 原文地址:https://www.cnblogs.com/wuyuxin/p/6994008.html
Copyright © 2020-2023  润新知