`

android 获取 内外存储设备路径疑问

 
阅读更多

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卡,难道我要一条一条路径去遍历?就算遍历到了,我也不知道哪条是内置存储,哪条是外置存储。而且以后哪个深井冰产商又整出一条路径出来,不就没完没了了嘛。

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

/**
	 * 获取外置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++;
		}

	}

 

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

 

  • 大小: 14.7 KB
  • 大小: 36 KB
  • 大小: 18.4 KB
  • 大小: 23 KB
分享到:
评论

相关推荐

    Android 获取内外置存储卡

    本文将深入探讨如何在Android平台上获取内外置存储卡的相关信息,包括路径、判断其是否存在以及如何加载SD卡。 首先,我们要了解Android设备的存储结构。Android系统通常包含两种类型的存储:内部存储(Internal ...

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

    在API 23及以上版本,Android引入了`StorageManager`类,其中包含了一些新的接口,例如`getStorageVolume()`,允许开发者更安全、可控地访问存储设备。不过,由于这些方法是隐藏的,所以需要使用反射来调用。在使用...

    Android获取内外置存储卡的方法

    本文将详细介绍如何在Android中正确地获取内外置存储卡的路径,并讨论Android不同版本中存储路径的变化,以及如何处理多存储卡和不同设备上的路径差异。 首先,Android在早期版本中,内外置存储卡通常可以通过硬...

    android 三种存储方式

    对于外部存储,可以使用Environment类获取SD卡路径,并通过File对象进行文件操作。需要注意的是,自Android 6.0(API级别23)起,你需要在运行时请求写入外部存储的权限。 在实际开发中,选择合适的存储方式很重要...

    Android判断获取内置外置sd卡demo

    总的来说,“Android判断获取内置外置sd卡demo”是一个实用的示例,涵盖了Android存储管理的关键概念,包括存储路径获取、权限管理以及在不同Android版本下的适配策略。开发者可以基于这个示例了解如何在实际应用中...

    android4.0中关于内外置sd卡的获取及读写权限问题.docx

    在Android 4.0中,可以通过`StorageManager`类来获取所有可用的存储设备信息。`StorageManager`类位于`framework/base/core/java/android/os/storage/`目录下,它提供了获取所有存储媒体的方法。 1. **获取Storage...

    URI.rar_android

    2. **文件URI**:以`file://`开头,直接指向设备上的文件路径。例如,`file:///storage/emulated/0/Pictures/image.jpg`表示的是SD卡上的一个图片文件。文件URI可以直接被File类处理,但要注意权限管理,特别是对于...

    sd.rar_SD卡

    SD卡,全称为Secure Digital Memory Card,是一种便携式存储设备,广泛应用于数码相机、手机、平板电脑等电子设备中。A1000设备可能是某种支持SD卡扩展存储的设备,如智能手机或者便携式媒体播放器。对于这种设备来...

    iMC EMO移动办公管理方案介绍.pptx

    对于不同类型的设备(如Android和iOS),注册过程略有差异,但总体包括用户登录请求、服务器响应、设备信息上报、策略获取等步骤。例如,Android设备会发送0x3001号报文进行用户登录,而iOS设备则发送0X2001号报文。...

    基于LBS的校园定位系统设计与实现.doc

    客户端运行在Android设备上,提供地图展示、用户定位、路径规划以及室内位置服务等功能;服务器端处理客户端的请求,进行数据处理和计算;数据库存储地图信息、定位数据和服务信息。 2. **定位技术**: - **Mobile...

    APP测试要点

    4. **存储空间测试**:当设备存储空间不足时,应用是否能给出明确提示。 5. **网络依赖性测试**:在无网络环境下尝试安装,验证是否有合理的提示信息。 6. **卸载测试**:确保应用可以从设备上完全卸载,不留任何...

    基于ARM的智能行车记录仪设计-论文

    主控模块通常采用性能卓越且功耗较低的ARM处理器,比如全志A33处理器,它不仅能够运行Android操作系统,还能够利用其内置的Mali400MP2 GPU进行图形处理。内存方面,需要使用高速的DDR2 SDRAM和非易失性的NAND Flash...

Global site tag (gtag.js) - Google Analytics