Android如何保存文件到sd卡,及期间遇到的各种问题

最近打算自己实现图片异步加载并实现三级缓存,其中保存文件部分使用到了sd卡保存,保存期间遇到了各种问题,下面细数一下遇到的问题及解决方式。

1、首先是sd卡是否存在及其路径获取问题

public static String getFileName(Context context, String url) {
        String result;
        String format = url.substring(url.lastIndexOf("."));
        String img_name = getPathEnCodesMD5(url) + format;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT){
                result = Environment.getExternalStorageDirectory() + "/Android/data/" + context.getPackageName() + "/cache/download_test/" + img_name;
            } else {
                File[] files = context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES);
                if (files.length > 1 && files[1] != null) {
                    result = files[1].toString() + "/" + img_name;
                } else {
                    result = files[0].toString() + "/" + img_name;
                }
            }
        } else {
            result = context.getCacheDir().getPath() + "/Android/data/" + context.getPackageName() + "/cache/download_test/" + img_name;
        }
        return result;
    }

通过上面的函数获取其中 context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES);会自动创建目录并返回路径名,是一个二维数组,在上面的 Environment.getExternalStorageState(),已经做出了判断,所以我认为存在sd卡并且 files[1]指向sd卡 ,之前并没有添加 files[1] != null的条件判断。

然而在一些手机上,其获取的数组长度为2,该手机确实有sd卡,files[1]却为空。

2、上面的context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES);获取路径的方式也应注意。

从api19 / Android 4.4 / KITKAT开始,Android为了更好的管理sd卡,对应用程序对sd卡的创建、删除、修改做了限制。只允许操作:sd卡路径下的Android/data/你的应用包名,该路径下的文件,这样是为了方便管理sd卡,防止应用卸载后在sd卡上残留一些文件。而该目录的创建官方给出了一些函数来实现,如下:

    ($rootDir)
+- /data                -> Environment.getDataDirectory()
|   |
|   |   ($appDataDir)
|   +- data/com.srain.cube.sample
|       |
|       |   ($filesDir)
|       +- files            -> Context.getFilesDir() / Context.getFileStreamPath("")
|       |       |
|       |       +- file1    -> Context.getFileStreamPath("file1")
|       |   ($cacheDir)
|       +- cache            -> Context.getCacheDir()
|       |
|       +- app_$name        ->(Context.getDir(String name, int mode)
|
|   ($rootDir)
+- /storage/sdcard0     -> Environment.getExternalStorageDirectory()
    |                       / Environment.getExternalStoragePublicDirectory("")
    |
    +- dir1             -> Environment.getExternalStoragePublicDirectory("dir1")
    |
    |   ($appDataDir)
    +- Andorid/data/com.srain.cube.sample
        |
        |   ($filesDir)
        +- files        -> Context.getExternalFilesDir("")
        |   |
        |   +- file1    -> Context.getExternalFilesDir("file1")
        |   +- Music    -> Context.getExternalFilesDir(Environment.Music);
        |   +- Picture  -> ... Environment.Picture
        |   +- ...
        |
        |   ($cacheDir)
        +- cache        -> Context.getExternalCacheDir()
        |
        +- ???
3、上面的两个问题还好解决,在此期间遇到了一个奇葩问题,最开始我以为是程序问题,各种找,结果找了一天也没找到,最后发现竟然是因为设备问题,我的手机是华为5.1.1,sd卡手机显示是低速sd卡。

问题的现象是:目录通过上面的函数创建成功,可是在保存图片时,无法保存成功。提示错误是没有权限。检查了AndroidManifest.xml,里面明明已经声明了权限。

解决办法:将sd卡拔出,重新插入即可。。。

最后发现这个不是偶然现象,我每次调试程序后,sd卡都会无法保存文件,而重新插拔后可以保存。。

参考资料:http://www.tuicool.com/articles/AvUnqiy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值