android App全局SD卡路径统一管理
16lz
2021-01-25
今天跟大家谈谈关于在app开发过程中,整个App路径的统一管理,特别是在android4.4的系统上,app在SD卡的读写权限以及创建子文件夹和文件都受到了android系统本身的限制。 网上关于这块的书写,其实很多,但是自己后面想了想,我个人觉得android app路径应该统一管理在这个目录/storage/sdcard0 or sdcard1/Android/data/<包名>/下,这样可以保证整个SD卡目录的清晰和不混乱!同时,当整个软件被卸载的时候,整个程序安装包名下的所有文件与资料都可以不删除掉,而不会导致多余的卸载残余,影响整个sd卡的目录结构,造成混乱与浪费! 好吧!说了那么多,上我整理的代码(不喜勿喷)AppPathManager.class:
/** * @类描述:app全局统一路径管理类 * @修改备注:所有的安卓开发者都应该按照这个方向走,不要再随意地再SD卡里建立各式各样的文件夹, * 而应该将所有应用数据都在/Android/data/内进行读写 * 。统一的规范并不违背开源的初衷, * 甚至有利于整个生态圈的有序发展。 */public class AppPathManager { /** * @方法说明:返回多个sd卡的该应用私有数据区的files目录 * @方法名称:getExternalRootFilesCachePath * @return:/storage/sdcard0 or sdcard1/Android/data/<包名>/files * @返回值:StringBuffer */ public static StringBuffer getExternalRootFilesCachePath() { return new StringBuffer(LynApplication.context.getExternalFilesDir( Environment.MEDIA_MOUNTED).getAbsolutePath()).append("/"); } /** * @方法说明:返回多个sd卡下该应用私有数据库的缓存目录 * @方法名称:getExternalRootCachePath * @return:/storage/sdcard0 or sdcard1/Android/data/<包名>/caches * @返回值:StringBuffer */ public static StringBuffer getExternalRootCachePath() { return new StringBuffer(LynApplication.context.getExternalCacheDir() .getAbsolutePath()).append("/"); } /** * @方法说明:图片保存路径(统一默认为:yyyy-MM-dd_HH:mm:ss.jpg, 方便后面自动清除) * @方法名称:getDownloadImagePath * @param type * @return * @返回值:String */ public static String getDownloadImagePath() { return getExternalRootCachePath() .append("image/") .append(DateTime.formatDate(new Date(), DateTime.DATE_PATTERN_13)).append(".jpg").toString(); } /** * @方法说明:Alog日志保存文件地址 * @方法名称:getAlogPath * @return * @返回值:String */ public static String getAlogPath() { return getExternalRootFilesCachePath().append("Alog/").toString(); } /** * 这两个方法是通过上下文对象Context获取的,只要应用程序被卸载,这两个目录下的文件都要被清空。 context.getCacheDir() * 获取应用程序自己的缓存目录 context.getExternalCacheDir() 获取应用程序在外部存储的存储目录 */ public static StringBuffer getInternalRootCachePath() { return new StringBuffer(LynApplication.context.getCacheDir() .getAbsolutePath()).append("/"); } /** * @方法说明:外置SD 卡公共目录,这些目录仍然可以切只允许访问,不受权限限制 * @方法名称:getExternalPublicPath * @return * @返回值:StringBuffer */ public static StringBuffer getExternalPublicPath() { return new StringBuffer(Environment.getExternalStoragePublicDirectory( Environment.MEDIA_MOUNTED).getAbsolutePath()) .append("/"); } /** * @方法说明:获取系统的根目录 * @方法名称:getSystemRoot * @return * @返回值:StringBuffer */ public static StringBuffer getSystemRoot() { return new StringBuffer(Environment.getRootDirectory() .getAbsolutePath()).append("/");// 获得系统主目录(/system) } /** * @方法说明:获取手机存储的WanKeXing根路径 * @方法名称:getRootFilePath * @return * @返回值:StringBuffer */ public static StringBuffer getRootFilePath() { if (hasSDCard()) { // 获得外部存储媒体目录(mnt/sdcard or /storage/sdcard0) return new StringBuffer(Environment.getExternalStorageDirectory() .getAbsolutePath()).append("/"); } else { // 获得data的目录(/data) return new StringBuffer(Environment.getDataDirectory() .getAbsolutePath()).append("/"); } } /** * @方法说明:判断SD卡是否存在 * @方法名称:hasSDCard * @return * @返回值:boolean */ public static boolean hasSDCard() { String status = Environment.getExternalStorageState(); if (!status.equals(Environment.MEDIA_MOUNTED)) { return false; } return true; } /** * @方法说明:清理掉十天前一天的缓存图片数据 * @方法名称:delImgCacheFileBeforeWeek * @返回值:void */ public static void delImgCacheFileBeforeWeek() { String needDelField = DateTime.formatDate(getDateBefore(10), DateTime.DATE_PATTERN_2); File file = new File(getExternalRootCachePath().toString()); if (file.exists() && file.isDirectory()) { File[] list = file.listFiles(); for (File file2 : list) { String name = file2.getName(); if (name.contains(needDelField)) { file2.delete(); } } } } /** * @方法说明:获取以前的时间 * @方法名称:getDateBefore * @param spanDay * @return * @返回值:Date */ private static Date getDateBefore(int spanDay) { Date nowtime = new Date(); Calendar now = Calendar.getInstance(); now.setTime(nowtime); now.set(Calendar.DATE, now.get(Calendar.DATE) - spanDay); return now.getTime(); }}
补充个日期转换:
public static final String GROUP_BY_EACH_DAY = "yyyyMMdd"; public static final String GROUP_BY_EACH_DAYSM = "yyyyMMddHHmmss"; public static final String GROUP_BY_EACH_SECOND = "yyyyMMddHHmm"; public final static String TIME_PATTERN = "HH:mm:ss";// 定义标准时间格式 public final static String DATE_PATTERN_1 = "yyyy/MM/dd";// 定义标准日期格式1 public final static String DATE_PATTERN_2 = "yyyy-MM-dd";// 定义标准日期格式2 public final static String DATE_PATTERN_3 = "yyyy/MM/dd HH:mm:ss";// 定义标准日期格式3,带有时间 public final static String DATE_PATTERN_4 = "yyyy/MM/dd HH:mm:ss E";// 定义标准日期格式4,带有时间和星期 public final static String DATE_PATTERN_5 = "yyyy年MM月dd日 HH:mm:ss E";// 定义标准日期格式5,带有时间和星期 public final static String DATE_PATTERN_6 = "yyyy-MM-dd HH:mm:ss";// 定义标准日期格式6,带有时间 public final static String DATE_PATTERN_7 = "yyyy年MM月dd日";// 定义标准日期格式7 public final static String DATE_PATTERN_8 = "yyyy-MM-dd HH:mm";// 定义标准日期格式8,带有时间 public final static String DATE_PATTERN_9 = "yy-MM-dd HH时";// 定义标准日期格式9,带有时间 public final static String DATE_PATTERN_10 = "yy/MM/dd HH:mm";// 定义标准日期格式10,带有时间 public final static String DATE_PATTERN_11 = "yy.MM.dd";// 定义标准日期格式11,带有时间 public final static String DATE_PATTERN_12 = "yyyyMMdd";// 定义标准日期格式12,带有时间 public final static String DATE_PATTERN_13 = "yyyy-MM-dd_HH:mm:ss";// 定义标准日期格式13,带有时间 /** * @方法说明:把一个日期,按照某种格式 格式化输出 * @方法名称:formatDate * @param date日期对象 * @param pattern格式模型 * @return * @返回值:String */ public static String formatDate(Date date, String pattern) { if (date != null) { SimpleDateFormat sdf = new SimpleDateFormat(pattern); return sdf.format(date); } return ""; }
根据我个人的习惯用法,我喜欢在整个app的实际开发中,真个app的全局路径还是用以下两个方法就完全ok了:
/** * @方法说明:返回多个sd卡的该应用私有数据区的files目录 * @方法名称:getExternalRootFilesCachePath * @return:/storage/sdcard0 or sdcard1/Android/data/<包名>/files * @返回值:StringBuffer */ public static StringBuffer getExternalRootFilesCachePath() { return new StringBuffer(LynApplication.context.getExternalFilesDir( Environment.MEDIA_MOUNTED).getAbsolutePath()).append("/"); } /** * @方法说明:返回多个sd卡下该应用私有数据库的缓存目录 * @方法名称:getExternalRootCachePath * @return:/storage/sdcard0 or sdcard1/Android/data/<包名>/caches * @返回值:StringBuffer */ public static StringBuffer getExternalRootCachePath() { return new StringBuffer(LynApplication.context.getExternalCacheDir() .getAbsolutePath()).append("/"); }
原因有以下几点:
1、整个app的storage/sdcard0 or sdcard1/Android/data/<包名>/该目录下,分别为caches和files两个文件夹
2、caches可以放些缓存类的文件,如图片缓存等。而files可以放些文件类的东西。这样的好处是统一了app的路径管理,防止了sd的结构混乱。
3、不管在4.4以上系统,在sd卡中都是可以任意读写的。同时当程序被卸载后,该storage/sdcard0 or sdcard1/Android/data/<包名> 目录下的东西都会被清空掉!防止了残留文件在sd卡的存留。这种残余的文件特别是在更新安装的时候,最容易了导致程序的数据错误和app的报错!
总之,app的全局路径在sd卡的管理是很重要的一环!不喜勿喷!若有不足,可以留言!一起学习!谢谢!
更多相关文章
- Python3原生编写月份计算工具
- Android6.0权限系统
- Android实现简单底部导航栏 Android仿微信滑动切换效果
- StevGuo系列文章翻译之Android中禁止屏保
- Android媒体播放---Media playback(二)
- Android动态加载补充 加载SD卡中的SO库
- Android中从源码分析关于AsyncTask的使用
- Looper,Handler,Message
- [Android] - 对话框的小框架 Managed-Dialog