关于android 4.2版本的sdcard文件目录分析(含修正)
2013-07-17 22:02
561 查看
最近的手机助手碰到一些关于sdcard目录的问题,特记下来以作备忘
在android 4.2版本之前,通过Environment.getExternalStorageDirectory()获取的sdcard默认目录是正常的,可进行读写,一般的结果是“/mnt/sdcard”,但是在4.2版本之后,获取的sdcard目录是“/storage/emulated/0”,使用File.exist()方法返回true表示文件/目录是存在的,但是通过adb向该返回的目录中写数据(上传文件=)是不成功的,返回的错误是"No
such file or directory",个人判断是返回的路径“/storage/emulated/0”其实是个类似快捷方式的文件,通过特定的解析方式可以认为是目录,但对于adb来说,该路径就是个文件,adb没有做过多的属性=判断。上述判断也是有依据的,通过adb的shell命令获取指定目录下的文件/文件夹列表, 该路径显示的是文件,且有大小。
之前就有猜测,关于目录结构中会存在不同程度的虚拟链接文件,google了下确实如此,以下的3处虚拟符号链接(类似windows下的快捷方式)是:
"/storage/emulated/0 and /storage/emulated/0/0 (new and "backup" locations, respectively)
/storage/emulated/legacy and /storage/emulated/legacy/0 (new and "backup" locations, respectively)
/storage/sdcard0 and /storage/sdcard0/0 (new and "backup" locations, respectively)" (文章链接是http://androidforums.com/verizon-galaxy-nexus-all-things-root/649940-4-2-sdcard-sdcard-0-observation.html)
所以在处理sdcard目录时,尽量自己先判断处理后提供同一的接口
获取sdcard目录时,统一有该类提供,以便兼容4.2的sdcard目录
注:至于通过Environment.getExternalStorageDirectory()获取的目录不能写入的问题,原因还不清楚,如果你知道,请告知,谢谢
注:以上是个人观察所得,难免有错误,如知晓,请告知
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//2013.05.10修正,关于目录/storage/emulated/legacy/目录的问题
因为google在4.2中考虑多用户的问题,对每个用户(user)来说,看各自的文件夹可以,但对于数据文件夹的处理就稍微麻烦了,所以调整了数据的挂载结构,如使用fuse技术/dev/fuse 会被挂载到/storage/emulated/0 目录,为了兼容以前,同时挂载到 /storage/emulated/legacy (故名思议,传统的),还建立三个软连接 /storage/sdcard0 ,/sdcard,/mnt/sdcard ,都指向
/storage/emulated/legacy/,(链接参见:http://bbs.gfan.com/android-5382920-1-1.html),但是就可能造成获取文件目录中的文件(如image)时,会出现相同的图片(本来上传1张,但出现了2张==)
将上面的类的判断修改如下
另外,针对image的上传后通过provider获取image图片时同一张图片给了2份,地址分别是"/storage/emulated/legacy/dcim/camera/1.jpg"和"/storage/sdcard0/DCIM/Camera/1.jpg",其中legacy的属于兼容的,但获取能获取出来,所以获取时要进行过滤处理
在android 4.2版本之前,通过Environment.getExternalStorageDirectory()获取的sdcard默认目录是正常的,可进行读写,一般的结果是“/mnt/sdcard”,但是在4.2版本之后,获取的sdcard目录是“/storage/emulated/0”,使用File.exist()方法返回true表示文件/目录是存在的,但是通过adb向该返回的目录中写数据(上传文件=)是不成功的,返回的错误是"No
such file or directory",个人判断是返回的路径“/storage/emulated/0”其实是个类似快捷方式的文件,通过特定的解析方式可以认为是目录,但对于adb来说,该路径就是个文件,adb没有做过多的属性=判断。上述判断也是有依据的,通过adb的shell命令获取指定目录下的文件/文件夹列表, 该路径显示的是文件,且有大小。
之前就有猜测,关于目录结构中会存在不同程度的虚拟链接文件,google了下确实如此,以下的3处虚拟符号链接(类似windows下的快捷方式)是:
"/storage/emulated/0 and /storage/emulated/0/0 (new and "backup" locations, respectively)
/storage/emulated/legacy and /storage/emulated/legacy/0 (new and "backup" locations, respectively)
/storage/sdcard0 and /storage/sdcard0/0 (new and "backup" locations, respectively)" (文章链接是http://androidforums.com/verizon-galaxy-nexus-all-things-root/649940-4-2-sdcard-sdcard-0-observation.html)
所以在处理sdcard目录时,尽量自己先判断处理后提供同一的接口
import java.io.File; import android.os.Environment; import android.text.TextUtils; public class CommonData { private static String CD_S_SdcardPath = ""; private static String CD_S_SdcardPathAbsolute = ""; public static String getSdcardPath(){ if (TextUtils.isEmpty(CD_S_SdcardPath)) CD_S_SdcardPath = Environment.getExternalStorageDirectory().getPath(); if (CD_S_SdcardPath.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated)) CD_S_SdcardPath = CD_S_SdcardPath.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard); return CD_S_SdcardPath; } public static String getAbsoluteSdcardPath(){ if (TextUtils.isEmpty(CD_S_SdcardPathAbsolute)) CD_S_SdcardPathAbsolute = Environment.getExternalStorageDirectory().getAbsolutePath(); if (CD_S_SdcardPathAbsolute.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated)) CD_S_SdcardPathAbsolute = CD_S_SdcardPathAbsolute.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard); return CD_S_SdcardPathAbsolute; } public static File getSdcardPathFile(){ return new File(getSdcardPath()); } public static String checkAndReplaceEmulatedPath(String strSrc){ if (strSrc.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated)) strSrc = strSrc.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard); return strSrc; } }其中
public static final String CT_S_Sdcard_Sign_Storage_emulated = "storage/emulated/"; public static final String CT_S_Sdcard_Sign_Storage_sdcard = "storage/sdcard";
获取sdcard目录时,统一有该类提供,以便兼容4.2的sdcard目录
注:至于通过Environment.getExternalStorageDirectory()获取的目录不能写入的问题,原因还不清楚,如果你知道,请告知,谢谢
注:以上是个人观察所得,难免有错误,如知晓,请告知
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//2013.05.10修正,关于目录/storage/emulated/legacy/目录的问题
因为google在4.2中考虑多用户的问题,对每个用户(user)来说,看各自的文件夹可以,但对于数据文件夹的处理就稍微麻烦了,所以调整了数据的挂载结构,如使用fuse技术/dev/fuse 会被挂载到/storage/emulated/0 目录,为了兼容以前,同时挂载到 /storage/emulated/legacy (故名思议,传统的),还建立三个软连接 /storage/sdcard0 ,/sdcard,/mnt/sdcard ,都指向
/storage/emulated/legacy/,(链接参见:http://bbs.gfan.com/android-5382920-1-1.html),但是就可能造成获取文件目录中的文件(如image)时,会出现相同的图片(本来上传1张,但出现了2张==)
将上面的类的判断修改如下
public class CommonData { private static String CD_S_SdcardPath = ""; private static String CD_S_SdcardPathAbsolute = ""; public static String getSdcardPath(){ if (TextUtils.isEmpty(CD_S_SdcardPath)) CD_S_SdcardPath = Environment.getExternalStorageDirectory().getPath(); CD_S_SdcardPath = checkAndReplaceEmulatedPath(CD_S_SdcardPath); return CD_S_SdcardPath; } public static String getAbsoluteSdcardPath(){ if (TextUtils.isEmpty(CD_S_SdcardPathAbsolute)) CD_S_SdcardPathAbsolute = Environment.getExternalStorageDirectory().getAbsolutePath(); CD_S_SdcardPathAbsolute = checkAndReplaceEmulatedPath(CD_S_SdcardPathAbsolute); return CD_S_SdcardPathAbsolute; } public static File getSdcardPathFile(){ return new File(getSdcardPath()); } public static String checkAndReplaceEmulatedPath(String strSrc){ <span style="color:#ff0000;">Pattern p = Pattern.compile("/?storage/emulated/\\d{1,2}"); Matcher m = p.matcher(strSrc); if (m.find()){ strSrc = strSrc.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard); }</span> // if (strSrc.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated) && !CD_S_SdcardPath.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated_legacy)) // strSrc = strSrc.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard); return strSrc; } }
另外,针对image的上传后通过provider获取image图片时同一张图片给了2份,地址分别是"/storage/emulated/legacy/dcim/camera/1.jpg"和"/storage/sdcard0/DCIM/Camera/1.jpg",其中legacy的属于兼容的,但获取能获取出来,所以获取时要进行过滤处理
相关文章推荐
- 关于android 4.2版本的sdcard文件目录分析(含修正)
- 关于android 4.2版本的sdcard文件目录分析(含修正)
- 关于android 4.2版本后的多用户目录结构分析(二)- /storage/sdcard0设定铃声失败
- 【android】下载文件至本应用程序的file目录或者sdcard
- 关于android开发中如何在sdcard中添加文件的说明
- 【android】下载文件至本应用程序的file目录或者sdcard
- Android 在sdcard中新建目录和复制文件
- Android SDCard文件、目录操作
- Android SDCard文件、目录操作一
- (转)关于android的4.2的0文件夹的详解(目录结构挂载分析)
- 更改 android 文件存放目录 getWritablePath() 为 sdCard
- Android 手机sdcard目录或文件的拷贝、移动、删除(递归)
- Android系统预制可卸载应用、预制文件到系统目录或SDCard目录
- Android 根目录和sdcard卡路径分析
- Android 读取sdcard指定目录文件
- Android在SDCard创建目录_卸载应用同时删除工程创建的文件
- 关于Android的sdcard目录的一点发现
- 关于通过DDMS向Android系统的模拟器的sdcard中导入mp3文件的问题
- [Android sdcard]eclipse ADT下DDMS视图sdcard(有的是storage目录)中无法导入文件
- Android SDcard目录文件操作