我的Android进阶之旅------>/storage/sdcard0, /sdcard, /mnt/sdcard ,/storage/emulated/legacy 的区别
转自:http://bbs.gfan.com/android-5382920-1-1.html
关于android的4.2的0文件夹的详解
---- android 4.0 ----
在galaxy nexus(GN)手机上userdata分区很大,被挂在/data目录,用户的数据通常是放在sd卡上,然而gn是没有sd卡的,所以google想了一个办法,就是虚拟一个。
所以,在userdata分区下有个目录叫media,是内置sd卡的数据存储位置,使用fuse技术将/data/media虚拟成为一个叫做/dev/fuse的设备,为了让程序能认出来,被同时挂载在 /mnt/sdcard 目录,
又为了兼容以前的程序,做了一个快捷方式(linux系统里叫软连接) /sdcard 指向的是 /mnt/sdcard .
当然,这些都是4.0的做法。
---- android 4.1 ----
在4.1里,同样也会使用fuse技术,/dev/fuse 会被同时挂载到/storage/sdcard0 目录,这个sdcard0表示第一个sd卡(如果有外置sd卡,那会多一个 /storage/sdcard1,比如我的xoom), /sdcard
软连接会指向 /storage/sdcard0 ,此时/mnt/sdcard 也是个软连接,会指向/storage/sdcard0。
如果你通过otg线接U盘,会被挂载到 /storage/usb0目录,stickmount这个软件为了让图库、快图、mx player等软件,能看到u盘里的数据,又同时挂载到 /storage/sdcard0/usStorage/sda1.
也许你会问,为什么不是usb0,而是sda1,这是linux的对硬盘的命名方式,如果你的u盘有多个分区,就分别是sda1,sda2这样一直排下去了。
---- android 4.2 ----
好了,我们开始说4.2系统。
谷歌是不是没事干啊,非要给android搞个多用户,你想想啊,在中国,可能因为经济问题,家里不是每人一个电脑,在美国,几乎需要用电脑的人,都会自己有一台或多台,一台电脑多人用的情况少之又少,这就是为什么叫PC了,顾名思义,个人电脑。像手机和平板这些东西,更加私人化了,很少公用了吧,我想在中国也是如此吧。
当然,谷歌也不完全是抽风,因为他有更大的战略部署,而且平板也的确有多人用的可能。
所以谷歌搞出来一个多用户,那每个人的应用、数据、个性配置都要分开吧。 应用和个性配置好弄,想想啊,通过权限控制,每人只能看自己的应用就行了,桌面也可以用自己的。
那数据怎么办????
好吧,调整用户数据的挂载结构。android 4.2,同样也会使用fuse技术/dev/fuse 会被挂载到/storage/emulated/0 目录,为什么是0呢,你还记得上边的sdcard0吧,第一个的意思。(如果有第二个,应该就是/storage/emulated/1,我们的三儿子没有外置sd卡,所以没法验证)
为了兼容以前,同时挂载到 /storage/emulated/legacy (故名思议,传统的),还建立三个软连接 /storage/sdcard0 ,/sdcard,/mnt/sdcard ,都指向 /storage/emulated/legacy
还有值得一提的是,4.2刚出来,这块变动又比较大,所以stickmount要升级到2.2之后,才可以通过otg挂载u盘了。
所以大家不用为0而苦恼了,这是正常的“生理特征”。
也许你会问,这个0和多用户有什么关系呢,那是因为多用户这个新特性,只在平板上才启用,在手机上会被禁用的。但是底层实现是一致的。 /mnt/shell/emulated 目录和 /storage/emulated 下的文件夹是一样的。(注意,这个/mnt/shell/emulated 不是挂载出来的)
由于我没有平板升级到4.2,所以只是推测,/mnt/shell/ 是为了多用户准备的,因为linux的多用户是基于shell实现的。
----------------2013-01-13-补充------------------------------------------------
4.2 在平板上的多用户
我前一段时间给XOOM Wifi刷上了CM10.1的4.2.1,成功开启多用户特性。新建的用户id从10开始。
默认用户的sdcard目录: /storage/emulated/0
新建的第一个用户的sdcard目录: /storage/emulated/10
新建的第二个用户的sdcard目录: /storage/emulated/11
关于0/0/0/0文件夹问题
是旧版本的CMW recovery在执行wipe data时导致建立新的0文件夹,请升级到cmw recovery 6.0.1.9 之后的版本,至于已经出现了多层0目录,请用RootExplorer剪切粘贴回/storage/emulated/0 下,推荐使用最新版CMW
recovery
===============转自:http://blog.csdn.net/gxj1680/article/details/8900270==================================================
最近的手机助手碰到一些关于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目录时,尽量自己先判断处理后提供同一的接口
- 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的属于兼容的,但获取能获取出来,所以获取时要进行过滤处理
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
http://android.stackexchange.com/questions/39542/confused-by-the-many-locations-of-the-virtual-sdcard
public static final String SDPATH = Environment .getExternalStorageDirectory().getAbsolutePath();
//获取外部存储的路径返回绝对路径的,其实就是你的SD卡的文件路径
/storage/sdcard
/sdcard
/mnt/sdcard
以上三者的区别?
/sdcard是/mnt/sdcard的符号链,指向/mnt/sdcard,
/storage/sdcard 是sdcard的分区……
/sdcard/: this is a symlink to...
/mnt/sdcard (Android < 4.0)
/storage/sdcard0 (Android 4.0+)
/storage/emulated/0/: to my knowledge, this refers to the "emulated MMC" ("owner part"). Usually this is the internal one. The "0" stands for the
user here, "0" is the first user aka device-owner. If you create additional users, this number will increment for each./storage/emulated/legacy/as before, but pointing to the part of the currently working user (for the owner, this would be a symlink to/storage/emulated/0/).
So this path should bring every user to his "part"./sdcard/: According to a comment
by Shywim, this is a symlink to.../mnt/sdcard(Android < 4.0)/storage/sdcard0(Android 4.0+)
/storage/sdcard0/: As there's nolegacypendant here (see comments below), the "0" in this case rather
identifies the device (card) itself. One could, eventually, connect a card reader with another SDCard via OTG, which then would become/storage/sdcard1(no proof for that, just a guess -- but I'd say a good one)
internal storage - Confused by the many locations of the virtual /sdcard/ - Android Enthusiasts Stack Exchange
====================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
====================================================================================
我的Android进阶之旅------>/storage/sdcard0, /sdcard, /mnt/sdcard ,/storage/emulated/legacy 的区别的更多相关文章
- 我的Android进阶之旅------>如何获取系统中定义了那些权限
在Window控制台中输入如下命令可以看到Android系统中列出的所有权限(如果自定义权限注册成功,在这里也会找到这些自定义的权限) adb shell pm list permissions C: ...
- [置顶] 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam
由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包括图像的文本信息).并简要说明实现方法. 答案:Android SDK支持例如以下显示富文本信息的方式. 1.使用T ...
- 【我的Android进阶之旅】推荐一款视频转换GIF图片格式的转换工具(Video to GIF)
一.背景 最近想把一些Android Demo的运行效果图获取下来,但是一直使用真机进行调试,在电脑上不好截取一段gif动画.而之前使用模拟器的时候可以使用 GifCam 工具进行屏幕动画截取.Gif ...
- 我的Android进阶之旅------>Android字符串资源中的单引號问题error: Apostrophe not preceded by 的解决的方法
刚刚在string字符串资源文件里,写了一个单引號.报错了,错误代码例如以下 error: Apostrophe not preceded by \ (in OuyangPeng's blog ) 资 ...
- 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法
我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...
- 我的Android进阶之旅------>解决Jackson等第三方转换Json的开发包在开启混淆后转换的实体类数据都是null的bug
1.错误描述 今天测试人员提了一个bug,说使用我们的app出现了闪退的bug,后来通过debug断点调试,发现我们的app转换服务器发送过来的json数据后,都是为null.而之前已经提测快一个月的 ...
- 我的Android进阶之旅------>关于android:layout_weight属性的详细解析
关于androidlayout_weight属性的详细解析 效果一 效果二 图3的布局代码 图4的布局代码 效果三 图7代码 图8代码 效果四 效果五 版权声明:本文为[欧阳鹏]原创文章,欢迎转载,转 ...
- 我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:
我的Android进阶之旅-->如何解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...
随机推荐
- 固态硬盘(Solid State Drives)
固态硬盘(Solid State Drives) 学习了:https://baike.baidu.com/item/%E5%9B%BA%E6%80%81%E7%A1%AC%E7%9B%98/45351 ...
- SpringMVC文件上传的配置
记述一下步骤以备查. 准备工作: 需要把Jakarta Commons FileUpload及Jakarta Commons io的包放lib里. 我这边的包是: commons-fileupload ...
- git学习——记录每次更新到仓库
记录每次更新到仓库 工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪.已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或 ...
- Win7 无法将快捷方式从任务栏移除怎么办
不知道是什么修改了系统的属性了.在网上找到了这个方法解决了:一:为了解决这个问题,你可以尝试下面的方法: 把以下命令分别输入到开始-运行中 1.cmd /k reg add "H ...
- 要做国外的app,使用到的分享和统计SDK推荐
国内的就不说了,多如牛毛,常用的是友盟,极光,shareSDK等等. 国外的统计有: Flurry(https://developer.yahoo.com) google analytics(http ...
- Nginx:HTTP框架是如何介入请求
参考资料 <深入理解Nginx>(陶辉) Nginx事件模块博客地址:http://www.cnblogs.com/runnyu/p/4914698.html Nginx是一个事件驱动构架 ...
- 【VBA】复制单元格批注
只复制单元格的批注该怎么操作呢?代码如下: Public Sub 复制单元格批注() Dim range1 As range Dim range2 As range '清除G列 Columns(&qu ...
- C# 中 finally 的用法
当一个异常抛出时,它会改变程序的执行流程.因此不能保证一个语句结束后,它后面的语句一定会执行,在 C# 中这个问题可以用 finally 解决. 为了确保一个语句总是能执行(不管是否抛出异常),需要将 ...
- ASP.NET基本对象介绍
ASP.NET能够成为一个庞大的软件体系,与它提供了大量的对象类库有很大的关系.这些类库中包含许多封装好的内置对象,开发人员可以直接使用这些对象的方法和属性,因此用较少的代码量就能轻松完成很多对象. ...
- 转: Appium ---移动自动化测试
转自:http://www.cnblogs.com/nbkhic/p/3803830.html 什么是appium? 下面这段介绍来自于appium的官网. Appium is an open-sou ...