热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

详解Android数据存储之Android6.0运行时权限下文件存储的思考

前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基

前言:

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

背景:

有关外置sdcard的读写权限


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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 最近团队在部署DLP,作为一个技术人员对于黑盒看不到的地方还是充满了好奇心。多次咨询乙方人员DLP的算法原理是什么,他们都以商业秘密为由避而不谈,不得已只能自己查资料学习,于是有了下面的浅见。身为甲方,虽然不需要开发DLP产品,但是也有必要弄明白DLP基本的原理。俗话说工欲善其事必先利其器,只有在懂这个工具的原理之后才能更加灵活地使用这个工具,即使出现意外情况也能快速排错,越接近底层,越接近真相。根据DLP的实际用途,本文将DLP检测分为2部分,泄露关键字检测和近似重复文档检测。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 本文介绍 MATLAB 中匿名函数的构造方法及其在实际编程中的应用。匿名函数是一种简洁的函数表达方式,可以直接在命令行或脚本中定义。例如,定义一个平方函数 `sqr = @(x) x.^2`。此外,匿名函数作为句柄对象,可以方便地传递计算函数,用于求解方程组等复杂问题,如 `fun = @(x) (x-3).*(x-5)`。 ... [详细]
  • 本文详细介绍了Linux系统中init进程的作用及其启动过程,解释了运行级别的概念,并提供了调整服务启动顺序的具体步骤和实例。通过了解这些内容,用户可以更好地管理系统的启动流程和服务配置。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
  • 信用评分卡的Python实现与评估
    本文介绍如何使用Python构建和评估信用评分卡模型,涵盖数据预处理、模型训练及验证指标选择。附带详细代码示例和视频教程链接。 ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • 本文介绍了一种解决二元可满足性(2-SAT)问题的方法。通过具体实例,详细解释了如何构建模型、应用算法,并提供了编程实现的细节和优化建议。 ... [详细]
  • 网易严选Java开发面试:MySQL索引深度解析
    本文详细记录了网易严选Java开发岗位的面试经验,特别针对MySQL索引相关的技术问题进行了深入探讨。通过本文,读者可以了解面试官常问的索引问题及其背后的原理。 ... [详细]
  •   上一篇博客中我们说到线性回归和逻辑回归之间隐隐约约好像有什么关系,到底是什么关系呢?我们就来探讨一下吧。(这一篇数学推导占了大多数,可能看起来会略有枯燥,但这本身就是一个把之前算法 ... [详细]
author-avatar
手机用户2602925995
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有