android 系统是开源的,于是各种产商各种瞎改android系统,工作了几个月,我发现单单就android的内外存储设备的路径我就不知道怎么获取了。上网查了几种方案,自己试验了下,感觉好迷茫啊。在这里记录下我试验的几种方案。

方案一:通过Enviroment类获取存储设备路径

android的官方文档上说,采用Enviroment.getExternalStorageDirectory()方法可以得到android设备的外置存储(即外插SDCARD),如果android设备有外插SDCARD的话就返回外插SDCARD的根目录路径,如果android设备没有外插SDCARD的话就返回android设备的内置SDCARD的路径。这套方案很快就被否决了,因为Enviroment类的这个方法里面的路径也是写死的,只有原生的android系统才使用这套方案,被更改过的anroid体统很多设备的路径都改了。

方案二:读取system/etc/vold.fstab文件的内容来获取存储设备路径

参考文档:http://blog.csdn.net/bbmiku/article/details/7937745

内置和外置SD卡的信息存在system/etc/vold.fstab 里面,我们可以从这里获得外置SD卡的路径。经本人实验,发现很多疑问。我的机子是三星I9300,我的机子没有外插SDCARD。通过eclipse获取vold.fstab文件,打开来看,有用的内容如下:

dev_mount sdcard /storage/extSdCard auto /devices/platform/s3c-sdhci.2/mmc_host/mmc1/

dev_mount sda /storage/UsbDriveA auto /devices/platform/s5p-ehci

dev_mount sdb /storage/UsbDriveB auto /devices/platform/s5p-ehci

dev_mount sdc /storage/UsbDriveC auto /devices/platform/s5p-ehci

dev_mount sdd /storage/UsbDriveD auto /devices/platform/s5p-ehci

dev_mount sde /storage/UsbDriveE auto /devices/platform/s5p-ehci

dev_mount sdf /storage/UsbDriveF auto /devices/platform/s5p-ehci

这里可没有我的内置SDCARD的路径啊,不懂。打开手机的文件系统发现我的内置的SDCARD路径是:/storage/emulated/0。于是我到eclipse的DDMS中去看下我的手机文件系统,发现storage路径下的文件结构为:

 从这个文件结构可以看出,真正有内容的应该是emulated/legacy和sdcard0才对,再从后面的连接来看,最后这两个目录都应该是指向/mnt/shell/emulated/0。接着打开/mnt/shell/emulated/0来看看,果然是我的sdcard目录


 这让我很疑惑,这样的话,读取vold.fstab文件来获取sdcard目录不就得不到/mnt/shell/emulated/0目录了么。方案二失败。

方案三:方案三的原理是linux命令,在命令窗口中输入 mount 或者 cat /proc/mounts 可得到系统挂载的存储。你也可以在DOS窗口中输入 adb shell -> mount ,或者 adb shell -> cat /proc/mounts 来查看( ”->“ 符号只是一个分割符,不要输)。好,我来DOS窗口中输入adb shell -> mount 来看下会得到什么


 这个我也看不懂,不过我猜最后一条应该是我的SDCARD的挂载了,因为有/mnt/shell/emulated 挂载路劲出现, 而/data/media是挂载的设备么?这是什么东西?好,我借部手机来看看,看其他的手机会mount出什么东西来。 那就借部note3来吧


 我借来的这部手机有外插SDCARD。可以看到最后两条应该是挂载SDCARD信息了。不过它的挂载设备是/dev/fuse, 和 /dev/block/vold/179:17  。 好吧,我晕了,等等,会不会 最后两条信息才是挂载SDCARD信息呢?我的是手机因为没有外插SDCARD,所以最后一条才是挂载SDCARD信息,有外插SDCARD的,最后两条是挂载SDCARD信息。这是规律?好吧,不是规律,我又借了部手机,mount了下,发现这个猜想纯属扯淡。

利用mount命令来获取SDCARD路径的方法,

参考:http://my.eoe.cn/1028320/archive/4718.html  和  http://www.eoeandroid.com/thread-275560-1-1.html。

方案四:

android常见的SD卡存储位置
/storage/emulated/0/
/storage/extSdCard
/mnt/external_sd/
/mnt/sdcard2/
/mnt/sdcard/external_sd/
/mnt/sdcard-ext/
/mnt/sdcard/
/storage/sdcard0/
/mnt/extSdCard/
/mnt/extsd/
/mnt/emmc/
/mnt/extern_sd/
/mnt/ext_sd/
/mnt/ext_card/
/mnt/_ExternalSD/
/sdcard2/
/sdcard/
/sdcard/sd/
/sdcard/external_sd/
/mnt/sd/
/mnt/
/storage/
/mnt/sdcard/sd/
/mnt/exsdcard/
/mnt/sdcard/extStorages/SdCard/
/ext_card/
/storage/extSdCard

3.0以上可以通过反射获取:

1 StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
2 // 获取sdcard的路径:外置和内置
3 String[] paths = (String[]) sm.getClass().getMethod("getVolumePaths"null).invoke(sm, null);

Android 4.1上

1 StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
2 String[] volumePaths = sm.getgetVolumePaths();

可以获得所有mount的SD卡,难道我要一条一条路径去遍历?就算遍历到了,我也不知道哪条是内置存储,哪条是外置存储。而且以后哪个深井冰产商又整出一条路径出来,不就没完没了了嘛。

我现在很郁闷,到底怎么弄才有一套最佳方案?跪求大神解救我。

目前最佳方案代码  
  1. /**
  2. * 获取外置SD卡路径
  3. *
  4. * @return
  5. */
  6. public static List<String> getSDCardPaths() {
  7. List<String> sdcardPaths = new ArrayList<String>();
  8. String cmd = "cat /proc/mounts";
  9. Runtime run = Runtime.getRuntime();// 返回与当前 Java 应用程序相关的运行时对象
  10. try {
  11. Process p = run.exec(cmd);// 启动另一个进程来执行命令
  12. BufferedInputStream in = new BufferedInputStream(p.getInputStream());
  13. BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
  14. String lineStr;
  15. while ((lineStr = inBr.readLine()) != null) {
  16. // 获得命令执行后在控制台的输出信息
  17. LogUtil.i("CommonUtil:getSDCardPath", lineStr);
  18. String[] temp = TextUtils.split(lineStr, " ");
  19. // 得到的输出的第二个空格后面是路径
  20. String result = temp[1];
  21. File file = new File(result);
  22. if (file.isDirectory() && file.canRead() && file.canWrite()) {
  23. LogUtil.d("directory can read can write:",
  24. file.getAbsolutePath());
  25. // 可读可写的文件夹未必是sdcard,我的手机的sdcard下的Android/obb文件夹也可以得到
  26. sdcardPaths.add(result);
  27. }
  28. // 检查命令是否执行失败。
  29. if (p.waitFor() != 0 && p.exitValue() == 1) {
  30. // p.exitValue()==0表示正常结束,1:非正常结束
  31. LogUtil.e("CommonUtil:getSDCardPath", "命令执行失败!");
  32. }
  33. }
  34. inBr.close();
  35. in.close();
  36. } catch (Exception e) {
  37. LogUtil.e("CommonUtil:getSDCardPath", e.toString());
  38. sdcardPaths.add(Environment.getExternalStorageDirectory()
  39. .getAbsolutePath());
  40. }
  41. optimize(sdcardPaths);
  42. for (Iterator iterator = sdcardPaths.iterator(); iterator.hasNext();) {
  43. String string = (String) iterator.next();
  44. Log.e("清除过后", string);
  45. }
  46. return sdcardPaths;
  47. }
  48. private static void optimize(List<String> sdcaredPaths) {
  49. if (sdcaredPaths.size() == 0) {
  50. return;
  51. }
  52. int index = 0;
  53. while (true) {
  54. if (index >= sdcaredPaths.size() - 1) {
  55. String lastItem = sdcaredPaths.get(sdcaredPaths.size() - 1);
  56. for (int i = sdcaredPaths.size() - 2; i >= 0; i--) {
  57. if (sdcaredPaths.get(i).contains(lastItem)) {
  58. sdcaredPaths.remove(i);
  59. }
  60. }
  61. return;
  62. }
  63. String containsItem = sdcaredPaths.get(index);
  64. for (int i = index + 1; i < sdcaredPaths.size(); i++) {
  65. if (sdcaredPaths.get(i).contains(containsItem)) {
  66. sdcaredPaths.remove(i);
  67. i--;
  68. }
  69. }
  70. index++;
  71. }
  72. }
/*** 获取外置SD卡路径* * @return*/public static List<String> getSDCardPaths() {List<String> sdcardPaths = new ArrayList<String>();String cmd = "cat /proc/mounts";Runtime run = Runtime.getRuntime();// 返回与当前 Java 应用程序相关的运行时对象try {Process p = run.exec(cmd);// 启动另一个进程来执行命令BufferedInputStream in = new BufferedInputStream(p.getInputStream());BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
     String lineStr;while ((lineStr = inBr.readLine()) != null) {// 获得命令执行后在控制台的输出信息LogUtil.i("CommonUtil:getSDCardPath", lineStr);String[] temp = TextUtils.split(lineStr, " ");// 得到的输出的第二个空格后面是路径String result = temp[1];File file = new File(result);if (file.isDirectory() &amp;&amp; file.canRead() &amp;&amp; file.canWrite()) {LogUtil.d("directory can read can write:",file.getAbsolutePath());// 可读可写的文件夹未必是sdcard,我的手机的sdcard下的Android/obb文件夹也可以得到sdcardPaths.add(result);}// 检查命令是否执行失败。if (p.waitFor() != 0 &amp;&amp; p.exitValue() == 1) {// p.exitValue()==0表示正常结束,1:非正常结束LogUtil.e("CommonUtil:getSDCardPath", "命令执行失败!");}}inBr.close();in.close();} catch (Exception e) {LogUtil.e("CommonUtil:getSDCardPath", e.toString());sdcardPaths.add(Environment.getExternalStorageDirectory().getAbsolutePath());}optimize(sdcardPaths);for (Iterator iterator = sdcardPaths.iterator(); iterator.hasNext();) {String string = (String) iterator.next();Log.e("清除过后", string);}return sdcardPaths;
}private static void optimize(List&lt;String&gt; sdcaredPaths) {if (sdcaredPaths.size() == 0) {return;}int index = 0;while (true) {if (index &gt;= sdcaredPaths.size() - 1) {String lastItem = sdcaredPaths.get(sdcaredPaths.size() - 1);for (int i = sdcaredPaths.size() - 2; i &gt;= 0; i--) {if (sdcaredPaths.get(i).contains(lastItem)) {sdcaredPaths.remove(i);}}return;}String containsItem = sdcaredPaths.get(index);for (int i = index + 1; i &lt; sdcaredPaths.size(); i++) {if (sdcaredPaths.get(i).contains(containsItem)) {sdcaredPaths.remove(i);i--;}}index++;}}</pre>

一定记得在manifest.xml中加权限

————————————————

如果你觉得本人的文章对你有所帮助,客官慢走赏瓶水喝

roid 获取 内外存储设备路径疑问相关推荐

  1. linux怎么挂载手机内部储存,Android获取内置、外置以及OTG等方式挂载的存储设备路径...

    众所周知,谷歌提供给了我们获取android内置存储卡的绝对路径的方法,但是如果要获取外置的存储的路径的话,谷歌就没有提供了.我们需要自己去写方法来获取这些路径,比如外置的tf卡,OTG挂载的U盘等. ...

  2. Android 文件外/内部存储的获取各种存储目录路径

    前言 对于任何一个应用来说,无论是PC端应用还是Android应用,存储肯定是必不可少的.对于很多做Android开发的同学来说,可能认为文件存储很简单,调用一些诸如getFilesDir,getEx ...

  3. 转--Android 文件外/内部存储的获取各种存储目录路径

    前言 对于任何一个应用来说,无论是PC端应用还是Android应用,存储肯定是必不可少的.对于很多做Android开发的同学来说,可能认为文件存储很简单,调用一些诸如getFilesDir,getEx ...

  4. Android 获取内外SD卡路径几种方法总结

    今天做项目的时候发现获取存储的方式不一样,搞了一个上午,计算sd卡的容量.总结一下.以免后面走弯路 Android 获取SD卡路径: 外置sd卡路径,也许很多同学在平时的工作中并不会用到,因为现在很多 ...

  5. android 获取默认存储路径,Android获取外置SD卡存储路径的方法

    在开发应用的过程中,经常会遇到需要获取设备存储路径的问题.而从网上看到的很多方法获取到的都是内置存储位置,并非外置SD卡路径,因此我推荐使用反射的机制来获取外置存储的路径. 通常,使用Environm ...

  6. 如何正确获得Android内外SD卡路径

    PS:看了9年的小说,自己开始动手写了一本,请各位猿们动动手指,点击下,有起点账号的可以收藏下!!<武意长存> 忘了这篇文章是在哪里看到了,当时就copy保存了下来,今天转载出来下. 外置 ...

  7. Android存储设备(U盘,SD卡)状态监测(《Android 2.3 SD卡挂载流程浅析1234567)

    我们是以DV6300-T的平台来做测试的,发现有2种方式来检测android中external media(包括SD卡,USB)的状态. 一种是使用StorageListener监听,还有一种是使用广 ...

  8. android下存储设备的使用

    本文转自android官网,原文地址:https://source.android.google.cn/devices/storage 1.概览 1.1.存储 Android 一直在不断发展,可支持各 ...

  9. Android中使用外置存储设备(U盘/移动硬盘等)

    本来是计划每个月至少写2篇博客的,可是2018年的第一个月就失言了.上个月实在是太忙了,从元旦收假上班开始,就开启了天天加班的新年征程,周六一样不放过. 谁让我是IT人呢?不过偶尔加班也没什么不好,对 ...

最新文章

  1. c 正则去除a以外的html,正则表达式:去除除SRC以外的HTML属性
  2. 脑电分析系列 | eeglab汇总
  3. 连接器篇(一) 低频系列
  4. 纯 as3 项目中引用 fl 包下的类
  5. 通俗易懂,常用线程池执行的-流程图
  6. 目前的计算机系统属于第三代电子计算机,计算机应用基础判断题
  7. Python-身份证核对
  8. python控制键盘事件、粘贴_python调用键盘控制游戏事件
  9. 《数学计算出题系统》功能规格说明书
  10. .net(偏web) vs j2ee的一些框架选型
  11. 《Redis设计与实现》阅读:Redis底层研究之简单动态字符串SDS
  12. java scjp考试_Java开发网 - 【经验】今天以96通过SCJP考试(含考试经验和部分真题)[转帖]...
  13. Spring框架爆RCE 0day漏洞的临时解决方案
  14. 如何理解模块、组件和对象
  15. react中dispatch_react-redux中dispatch是异步?
  16. 我的世界服务器自定义附魔外挂,我的世界怎么用命令方块刷自定义附魔神器
  17. 陪玩源码,根据用户需求和功能开发搭建
  18. Y05 - 999、Python - 风变编程
  19. 小白装系统(超详细)
  20. Mysql根据经纬度和距离检索符合条件的数据浅析

热门文章

  1. 「大数据的关键思考系列」21:阿里巴巴运营数据的外三板斧之“存、管、用”(下)...
  2. C语言解析IPv4地址段 - 获取地址总数即每个IP地址
  3. Nat Genet | 湖南农业大学群体基因组学研究揭示古老芥菜身世之谜、百变之源
  4. 使用Python Pandas处理亿级数据
  5. 【毕业设计】履带四足复合机器人
  6. 湖南工业大学计算机类排名,湖南十强高校公布,这三所大学排名倒数,湖南工业大学排名最后...
  7. 渲染层网络层错误--微信小程序
  8. 5.gstreamer RTSP硬件解码播放器
  9. c# is 的用法
  10. html怎么按钮设置字体大小,更改按一个按钮的HTML字体大小