android App全局SD卡路径统一管理

    今天跟大家谈谈关于在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卡的管理是很重要的一环!不喜勿喷!若有不足,可以留言!一起学习!谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值