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 ...
随机推荐
- BindingFlags说明
为了获取返回值,必须指定 BindingFlags.Instance 或 BindingFlags.Static. 指定 BindingFlags.Public 可在搜索中包含公共成员. 指定 Bin ...
- ECNU1104-BFS
简单的BFS题意:多起点多终点 /* 简单的BFS 题意:多起点多终点 */ #include<stdio.h> #include<string.h> #include< ...
- Android 图片缩放
以下演示将一个ImageView的高度设置为两倍: 布局文件main.xml <?xml version="1.0" encoding="utf-8"?& ...
- BZOJ 3123 SDOI2013 森林
首先对于查询操作就是裸的COT QAQ 在树上DFS建出主席树就可以了 对于连接操作,我们发现并没有删除 所以我们可以进行启发式合并,每次将小的树拍扁插入大的树里并重构即可 写完了之后第一个和第二个点 ...
- winform自定义文件程序-- 不允许所请求的注册表访问权(ZSSQL)
常见问题1: 不允许所请求的注册表访问权 win7.win8 双击程序文件ZSSQL时候会出现 不允许所请求的注册表访问权 的弹窗异常 解决方法:ZSSQL.exe 右键 属性--兼容性--以管理员身 ...
- Android 应用开发性能优化完全分析
1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...
- java编解码技术,json序列化与二进制序列化
1.何为json序列化与二进制序列化 通常我们在程序中采用的以json为传输,将json转为对象的就是json序列化了.而二进制序列化通常是我们将数据转换为二进制进行传输,然后在进行各类转换操作 2. ...
- How to change data dir of mysql?
# 1 copy orgin data dir of mysql to new one cp -R /var/lib/mysql /mysqldata chown mysql:mysql -R /my ...
- Angularjs checkbox的ng属性
angularjs 默认给 input[checkbox] 元素定制了一些属性,如: <input type="checkbox" ng-mudel="name&q ...
- Maven、gradle、Ant、Eclipse IDE
Maven.gradle.Ant.Eclipse IDE之间的关系 http://wenku.baidu.com/view/d33208810912a21615792910.html?from=sea ...