roid 获取 内外存储设备路径疑问
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卡,难道我要一条一条路径去遍历?就算遍历到了,我也不知道哪条是内置存储,哪条是外置存储。而且以后哪个深井冰产商又整出一条路径出来,不就没完没了了嘛。
我现在很郁闷,到底怎么弄才有一套最佳方案?跪求大神解救我。
![](/images/icon_star.png)
![](/images/spinner.gif)
- /**
- * 获取外置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() && file.canRead() && file.canWrite()) {
- LogUtil.d("directory can read can write:",
- file.getAbsolutePath());
- // 可读可写的文件夹未必是sdcard,我的手机的sdcard下的Android/obb文件夹也可以得到
- sdcardPaths.add(result);
- }
- // 检查命令是否执行失败。
- if (p.waitFor() != 0 && 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<String> sdcaredPaths) {
- if (sdcaredPaths.size() == 0) {
- return;
- }
- int index = 0;
- while (true) {
- if (index >= sdcaredPaths.size() - 1) {
- String lastItem = sdcaredPaths.get(sdcaredPaths.size() - 1);
- for (int i = sdcaredPaths.size() - 2; i >= 0; i--) {
- if (sdcaredPaths.get(i).contains(lastItem)) {
- sdcaredPaths.remove(i);
- }
- }
- return;
- }
- String containsItem = sdcaredPaths.get(index);
- for (int i = index + 1; i < sdcaredPaths.size(); i++) {
- if (sdcaredPaths.get(i).contains(containsItem)) {
- sdcaredPaths.remove(i);
- i--;
- }
- }
- index++;
- }
- }
/*** 获取外置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() && file.canRead() && file.canWrite()) {LogUtil.d("directory can read can write:",file.getAbsolutePath());// 可读可写的文件夹未必是sdcard,我的手机的sdcard下的Android/obb文件夹也可以得到sdcardPaths.add(result);}// 检查命令是否执行失败。if (p.waitFor() != 0 && 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<String> sdcaredPaths) {if (sdcaredPaths.size() == 0) {return;}int index = 0;while (true) {if (index >= sdcaredPaths.size() - 1) {String lastItem = sdcaredPaths.get(sdcaredPaths.size() - 1);for (int i = sdcaredPaths.size() - 2; i >= 0; i--) {if (sdcaredPaths.get(i).contains(lastItem)) {sdcaredPaths.remove(i);}}return;}String containsItem = sdcaredPaths.get(index);for (int i = index + 1; i < sdcaredPaths.size(); i++) {if (sdcaredPaths.get(i).contains(containsItem)) {sdcaredPaths.remove(i);i--;}}index++;}}</pre>
一定记得在manifest.xml中加权限
————————————————
如果你觉得本人的文章对你有所帮助,客官慢走赏瓶水喝
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
roid 获取 内外存储设备路径疑问相关推荐
- linux怎么挂载手机内部储存,Android获取内置、外置以及OTG等方式挂载的存储设备路径...
众所周知,谷歌提供给了我们获取android内置存储卡的绝对路径的方法,但是如果要获取外置的存储的路径的话,谷歌就没有提供了.我们需要自己去写方法来获取这些路径,比如外置的tf卡,OTG挂载的U盘等. ...
- Android 文件外/内部存储的获取各种存储目录路径
前言 对于任何一个应用来说,无论是PC端应用还是Android应用,存储肯定是必不可少的.对于很多做Android开发的同学来说,可能认为文件存储很简单,调用一些诸如getFilesDir,getEx ...
- 转--Android 文件外/内部存储的获取各种存储目录路径
前言 对于任何一个应用来说,无论是PC端应用还是Android应用,存储肯定是必不可少的.对于很多做Android开发的同学来说,可能认为文件存储很简单,调用一些诸如getFilesDir,getEx ...
- Android 获取内外SD卡路径几种方法总结
今天做项目的时候发现获取存储的方式不一样,搞了一个上午,计算sd卡的容量.总结一下.以免后面走弯路 Android 获取SD卡路径: 外置sd卡路径,也许很多同学在平时的工作中并不会用到,因为现在很多 ...
- android 获取默认存储路径,Android获取外置SD卡存储路径的方法
在开发应用的过程中,经常会遇到需要获取设备存储路径的问题.而从网上看到的很多方法获取到的都是内置存储位置,并非外置SD卡路径,因此我推荐使用反射的机制来获取外置存储的路径. 通常,使用Environm ...
- 如何正确获得Android内外SD卡路径
PS:看了9年的小说,自己开始动手写了一本,请各位猿们动动手指,点击下,有起点账号的可以收藏下!!<武意长存> 忘了这篇文章是在哪里看到了,当时就copy保存了下来,今天转载出来下. 外置 ...
- Android存储设备(U盘,SD卡)状态监测(《Android 2.3 SD卡挂载流程浅析1234567)
我们是以DV6300-T的平台来做测试的,发现有2种方式来检测android中external media(包括SD卡,USB)的状态. 一种是使用StorageListener监听,还有一种是使用广 ...
- android下存储设备的使用
本文转自android官网,原文地址:https://source.android.google.cn/devices/storage 1.概览 1.1.存储 Android 一直在不断发展,可支持各 ...
- Android中使用外置存储设备(U盘/移动硬盘等)
本来是计划每个月至少写2篇博客的,可是2018年的第一个月就失言了.上个月实在是太忙了,从元旦收假上班开始,就开启了天天加班的新年征程,周六一样不放过. 谁让我是IT人呢?不过偶尔加班也没什么不好,对 ...
最新文章
- c 正则去除a以外的html,正则表达式:去除除SRC以外的HTML属性
- 脑电分析系列 | eeglab汇总
- 连接器篇(一) 低频系列
- 纯 as3 项目中引用 fl 包下的类
- 通俗易懂,常用线程池执行的-流程图
- 目前的计算机系统属于第三代电子计算机,计算机应用基础判断题
- Python-身份证核对
- python控制键盘事件、粘贴_python调用键盘控制游戏事件
- 《数学计算出题系统》功能规格说明书
- .net(偏web) vs j2ee的一些框架选型
- 《Redis设计与实现》阅读:Redis底层研究之简单动态字符串SDS
- java scjp考试_Java开发网 - 【经验】今天以96通过SCJP考试(含考试经验和部分真题)[转帖]...
- Spring框架爆RCE 0day漏洞的临时解决方案
- 如何理解模块、组件和对象
- react中dispatch_react-redux中dispatch是异步?
- 我的世界服务器自定义附魔外挂,我的世界怎么用命令方块刷自定义附魔神器
- 陪玩源码,根据用户需求和功能开发搭建
- Y05 - 999、Python - 风变编程
- 小白装系统(超详细)
- Mysql根据经纬度和距离检索符合条件的数据浅析
热门文章
- 「大数据的关键思考系列」21:阿里巴巴运营数据的外三板斧之“存、管、用”(下)...
- C语言解析IPv4地址段 - 获取地址总数即每个IP地址
- Nat Genet | 湖南农业大学群体基因组学研究揭示古老芥菜身世之谜、百变之源
- 使用Python Pandas处理亿级数据
- 【毕业设计】履带四足复合机器人
- 湖南工业大学计算机类排名,湖南十强高校公布,这三所大学排名倒数,湖南工业大学排名最后...
- 渲染层网络层错误--微信小程序
- 5.gstreamer RTSP硬件解码播放器
- c# is 的用法
- html怎么按钮设置字体大小,更改按一个按钮的HTML字体大小