前言:

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

Android数据存储之Android 6.0运行时权限下文件存储的思考的更多相关文章

  1. Android开发学习之路-Android6.0运行时权限

    在Android6.0以后开始,对于部分敏感的“危险”权限,需要在应用运行时向用户申请,只有用户允许的情况下这个权限才会被授予给应用.这对于用户来说,无疑是一个提升安全性的做法.那么对于开发者,应该怎 ...

  2. Android 6.0+ 运行时权限

    1.权限被分为了普通和危险两种 2.打电话的Demo import android.Manifest; import android.app.Activity; import android.cont ...

  3. Android权限管理之Android 6.0运行时权限及解决办法

    前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...

  4. Android6.0运行时权限(基于RxPermission开源库)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 在6.0以前的系统,都是权限一刀切的处理方式,只要用户安装,Manifest申请的权限都会被赋予,并且安装后权限也撤销不了. And ...

  5. Android8.0运行时权限策略变化和适配方案

    版权声明:转载必须注明本文转自严振杰的博客:http://blog.yanzhenjie.comAndroid8.0也就是Android O即将要发布了,有很多新特性,目前我们可以通过AndroidS ...

  6. 谈谈Android 6.0运行时权限理解

    前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...

  7. Android 6.0 运行时权限处理完全解析

    一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http:// ...

  8. android-详解Android 6.0运行时权限

    感谢郭神,从Android 6.0开始,不再是安装应用时用户确定获得全部的权限.而是在使用软件过程中需要该权限时,弹出对话框让用户选择权限.不仅如此,用户选择权限后还可以关闭. 检查是否获得权限 通过 ...

  9. Android 6.0运行时权限

    一.Runtime Permissions Android 6.0在手机安全方面做的一个处理就是增加了运行时权限(Runtime Permissions). 新的权限机制更好的保护了用户的隐私,Goo ...

随机推荐

  1. [APUE]UNIX进程的环境(下)

    一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函 ...

  2. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  3. 细说WebSocket - Node篇

    在上一篇提高到了 web 通信的各种方式,包括 轮询.长连接 以及各种 HTML5 中提到的手段.本文将详细描述 WebSocket协议 在 web通讯 中的实现. 一.WebSocket 协议 1. ...

  4. Win10 IIS本地部署网站运行时图片和样式不正常?

    后期会在博客首发更新:http://dnt.dkill.net 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 启用关闭win功 ...

  5. ExtJS 4.2 业务开发(一)主页搭建

    本篇开始搭建一个ExtJS 4.2单页面应用, 这里先介绍主页的搭建,内容包括:主页结构说明.扩展功能等方面. 目录 1. 主页结构说明 2. 扩展功能 3. 在线演示 1. 主页结构说明 1.1 主 ...

  6. 谱聚类(spectral clustering)原理总结

    谱聚类(spectral clustering)是广泛使用的聚类算法,比起传统的K-Means算法,谱聚类对数据分布的适应性更强,聚类效果也很优秀,同时聚类的计算量也小很多,更加难能可贵的是实现起来也 ...

  7. 使用github远程仓库

    经过几天对github的研究,终于把自己想完成的给解决了,发现google真的有很多解释,但是很多也会出现一些bug,对于初学者真的很多烦恼,所以整理一份,能给初识github的你有所帮助 一,首先, ...

  8. 【JavaScript】javascript中伪协议(javascript:)使用探讨

    javascript:这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的解释器运行. 比如下面这个死链接: <a href="javasc ...

  9. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...

  10. SQL字符串函数

    LEN() :计算字符串长度(字符的个数.)datalength();//计算字符串所占用的字节数,不属于字符串函数.测试varchar变量与nvarchar变量存储字符串a的区别.见备注1.LOWE ...