Android应用正确使用扩展SD卡,特别是安卓4.4以后的版本
Android 开发时如何正确获取使用扩展存储路径
在 2.x 版本中,Android设备都是单存储,第三方App写文件,必须申请 WRITE_EXTERNAL_STORAGE 权限;
在4.0之后,Android设备开始有了内置闪存,即 primary storage,并且可以外置SD卡,即 secondary external storage device;
WRITE_EXTERNAL_STORAGE 权限变成了仅仅控制 primary storage,同时引入了 WRITE_MEDIA_STORAGE 权限来控制secondary external storage device的操作。
到了Android 4.4 KitKat,WRITE_MEDIA_STORAGE 权限仅提供给系统应用,不再授予第三方App。
关于 secondary external storage device 的写操作也有了新规定。
Android的文档是这么写的:
Link: http://source.android.com/devices/tech/storage/index.html:
The WRITE_EXTERNAL_STORAGE permission must only grant write access to
the primary external storage on a device. Apps must not be allowed to
write to secondary external storage devices, except in their
package-specific directories as allowed by synthesized permissions.
Restricting writes in this way ensures the system can clean up files
when applications are uninstalled.
翻译:
WRITE_EXTERNAL_STORAGE 权限,仅仅用于授权用户写 primary external storage。对于secondary external storage devices,除了与自己包名相关的文件夹之外,应用程序不允许写secondary external storage devices的其它区域。这样限制的目的是为了在应用被卸载的时候这些外部文件能得到很好的清除。
举例来说,如果应用的包名是com.example.foo,那么外部存储上的Android/data/com.example.foo/文件夹就可随意访问,其他任何地方都不允许写,并且,存储在自己包名相关的文件夹的文件,当该应用被卸载时候也会随之被清除。
分情况来说:
只有外部存储的设备
这种设备一般是android4.0之前的,只有一个存储,不受这个规则限制,还是可以随便读写,但如果你刷了4.4系统,那么就只能写自己包名相关的文件夹了。 只有内部存储的设备
比如Nexus系列,sony L系列,不受这个规则限制,但是建议在自己的包名相关的文件夹写数据。 既有内部存储又有外部存储
需要遵守这个规定,不能在外部存储乱写了,需要在自己的包名相关的文件夹写数据。
Google做了这个限制后解决了这个问题:
随便一个App,都会在/sdcard、/sdcard1 上建一个目录,删了也会重新建,即使被卸载,也会留下一些垃圾文件。
但是,也产生了一个问题:
类似于视频、图像处理这种想在外部存储缓存大量音视频文件,并且App被卸载后还想保留的,就没办法了。
开发中应该怎么使用?
作为一个程序员,想必你也很讨厌App在SD卡根目录乱建目录吧,那就从我做起,来遵守Google的这一规定吧。
通过Context.getExternalFilesDir()方法可以获取到 SDCard/Android/data/{package_name}/files/ ,储存一些长时间保存的数据;
通过Context.getExternalCacheDir()方法可以获取到 SDCard/Android/data/{package_name}/cache/,储存临时缓存数据;
这两个目录分别对应 设置->应用->应用详情里面的”清除数据“与”清除缓存“选项。
一个获取外部存储Cache的例子:
/**
* 获取拓展存储Cache的绝对路径
* @param context
*/
public static String getExternalCacheDir(Context context) {
if (!isMounted())
return null; StringBuilder sb = new StringBuilder();
File file = context.getExternalCacheDir();
// In some case, even the sd card is mounted, getExternalCacheDir will return null may be it is nearly full.
if (file != null) {
sb.append(file.getAbsolutePath()).append(File.separator);
} else {
sb.append(Environment.getExternalStorageDirectory().getPath())
.append("/Android/data/").append(context.getPackageName())
.append("/cache/").append(File.separator).toString();
} return sb.toString();
}
Android应用正确使用扩展SD卡,特别是安卓4.4以后的版本的更多相关文章
- Android 下载文件及写入SD卡
Android 下载文件及写入SD卡,实例代码 <?xml version="1.0" encoding="utf-8"?> <LinearL ...
- android文件缓存,并SD卡创建目录未能解决和bitmap内存溢出解决
1.相关代码: 加入权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ...
- [android] 分析setting源代码获取SD卡大小
保存文件到sd卡需要判断sd卡的大小,通过查看android系统的自带应用的源代码,得到方法,sdk下面的source是sdk的源代码,包含的是android.Jar下面的所有class的源代码.在a ...
- 【译】如何在 Android 5.0 上获取 SD卡 的读写权限
因为最近项目需要,涉及到 SD卡 的读写操作,然而申请 <!-- 读写权限 --> <uses-permission android:name="android.permi ...
- File存对象--android 的File存储到SD卡();
方法1:android File存对象--File存储到SD卡(); 1.保存对象到本地或SD卡需要注意的是,要保存的对象(OAuthV1)一定要实现了Serializable接口.实现了Serial ...
- Android中使用SQLiteOpenHelper管理SD卡中的数据库
使用Android中自带的SQLiteOpenHelper可以完成数据库的创建与管理,但有两点局限: (1)数据库创建在内存卡中,大小受限,创建位置位于/data/data/应用程序名/databas ...
- android学习笔记47——读写SD卡上的文件
读写SD卡上的文件 通过Context的openFileInput.openFileOutput来打开文件输入流.输出流时,程序打开的都是应用程序的数据文件夹里的文件,其存储的文件大小可能都比较有限- ...
- 6、android 普通日志输出到SD卡
这是本人见过写博文最负责的一个人: http://www.crifan.com/android_try_use_android_logging_log4j_to_output_log_to_sd_ca ...
- Android 将文件保存到SD卡中
①写文件到sd卡中需要获得权限,在AndroidManifest.xml中添加如下权限: <uses-permission android:name="android.permissi ...
随机推荐
- 支付宝Unity
原地址:http://blog.csdn.net/sgnyyy/article/details/20444627 说明:支付宝Android的SDK接入只有一个接口,付费. 1. Android代码的 ...
- python url编码
1.quote:使用适合URL内容的转义序列替换String中的特殊字符. 2.quote_plus:调用quote并使用“+”替换所有空格 3.unquote:使用转义字符的单字符对应物替换'%xx ...
- C#日期格式及其运算
C#日期时间格式化 转载: http://www.cnblogs.com/hantianwei/archive/2010/09/23/1833228.html
- Zookeeper + Hadoop + Hbase部署备忘
网上类似的文章很多,本文只是记录下来备忘.本文分四大步骤: 准备工作.安装zookeeper.安装hadoop.安装hbase,下面分别详细介绍: 一 准备工作 1. 下载 zookeeper.had ...
- 数据库存储安全之(MD5+盐)加密
一般系统数据库密码加密方式: MD5后存入数据库 SHA1 Hash后存入数据库 缺点:黑客可以通过密码暴力破解获取密码信息,具体做法是将常用密码进行Hash后做成一个字典, 破解的时候,只需要查字典 ...
- wince下sources\sources.cmn\Makefile.def的相关作用
1:首先是Makefile.def: ---------------------------------------- 在所有驱动的makefile中有!INCLUDE $(_MAKEENVROOT) ...
- bzoj1588,1208,1503
进入splay tree的学习中: 据说splay tree在理论上功能十分强大,好好学: splay首先一定是一棵BST,所以记不得的时候画个图就明白: 首先总结一下splay基本的操作左旋,右旋: ...
- UVa 129 (回溯法) Krypton Factor
回溯法确实不是很好理解掌握的,学习紫书的代码细细体会. #include <cstdio> ]; int n, L, cnt; int dfs(int cur) { if(cnt++ == ...
- boostrap兼容ie及其案例
多梦网络 wordpress主题 http://www.dmeng.net/
- hdu 2955 Robberies
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...