Android中获取文件存储位置(内部存储或者扩展SD卡)
16lz
2021-01-23
我们通常用Environment.getExternalStorageDirectory().getAbsolutePath()来获取手机上的文件存储位置,但是不同的设备上,调用getExternalStorageDirectory()返回值却不一样。查询了Android的文档,才找到原因,
原来这个方法返回的是当前设备厂商所认为的“外部存储”,有可能返回外置的SD卡目录(Micro SD Card),也可能返回内置的存储目(eMMC)。
一部分手机将eMMC存储挂载到 /mnt/external_sd 、/mnt/sdcard2 等节点,而将外置的SD卡挂载到 Environment.getExternalStorageDirectory()这个结点。
此时,调用Environment.getExternalStorageDirectory(),则返回外置的SD的路径。
而另一部分手机直接将eMMC存储挂载在Environment.getExternalStorageDirectory()这个节点,而将真正的外置SD卡挂载到/mnt/external_sd、/mnt/sdcard2 等节点。
此时,调用Environment.getExternalStorageDirectory(),则返回内置的SD的路径。
至此就能解释为都是无外置SD卡的情况下,在中兴手机或者三星上,调用
原来这个方法返回的是当前设备厂商所认为的“外部存储”,有可能返回外置的SD卡目录(Micro SD Card),也可能返回内置的存储目(eMMC)。
一部分手机将eMMC存储挂载到 /mnt/external_sd 、/mnt/sdcard2 等节点,而将外置的SD卡挂载到 Environment.getExternalStorageDirectory()这个结点。
此时,调用Environment.getExternalStorageDirectory(),则返回外置的SD的路径。
而另一部分手机直接将eMMC存储挂载在Environment.getExternalStorageDirectory()这个节点,而将真正的外置SD卡挂载到/mnt/external_sd、/mnt/sdcard2 等节点。
此时,调用Environment.getExternalStorageDirectory(),则返回内置的SD的路径。
至此就能解释为都是无外置SD卡的情况下,在中兴手机或者三星上,调用
打印 Environment.getExternalStorageState(),却返回 ”removed“,在索尼、MOTO G上就返回:“mounted”
下面这个方法可以获取手机的可以存储,包括SD卡、TF卡等,对多存储卡进行了匹配,详细的代码如下:
转载自:http://blog.csdn.net/zqs62761130/article/details/42464785
1 public class SDCardScanner { 2 /* 3 * avoid initializations of tool classes 4 */ 5 private SDCardScanner() { 6 } 7 8 /** 9 * @Title: getExtSDCardPaths10 * @Description: to obtain storage paths, the first path is theoretically11 * the returned value of12 * Environment.getExternalStorageDirectory(), namely the13 * primary external storage. It can be the storage of internal14 * device, or that of external sdcard. If paths.size() >1,15 * basically, the current device contains two type of storage:16 * one is the storage of the device itself, one is that of17 * external sdcard. Additionally, the paths is directory.18 * @return List19 * @throws IOException20 */21 public static List getExtSDCardPaths() {22 List paths = new ArrayList ();23 String extFileStatus = Environment.getExternalStorageState();24 File extFile = Environment.getExternalStorageDirectory();25 if (extFileStatus.equals(Environment.MEDIA_MOUNTED)26 && extFile.exists() && extFile.isDirectory()27 && extFile.canWrite()) {28 paths.add(extFile.getAbsolutePath());29 }30 try {31 // obtain executed result of command line code of 'mount', to judge32 // whether tfCard exists by the result33 Runtime runtime = Runtime.getRuntime();34 Process process = runtime.exec("mount");35 InputStream is = process.getInputStream();36 InputStreamReader isr = new InputStreamReader(is);37 BufferedReader br = new BufferedReader(isr);38 String line = null;39 int mountPathIndex = 1;40 while ((line = br.readLine()) != null) {41 // format of sdcard file system: vfat/fuse42 if ((!line.contains("fat") && !line.contains("fuse") && !line43 .contains("storage"))44 || line.contains("secure")45 || line.contains("asec")46 || line.contains("firmware")47 || line.contains("shell")48 || line.contains("obb")49 || line.contains("legacy") || line.contains("data")) {50 continue;51 }52 String[] parts = line.split(" ");53 int length = parts.length;54 if (mountPathIndex >= length) {55 continue;56 }57 String mountPath = parts[mountPathIndex];58 if (!mountPath.contains("/") || mountPath.contains("data")59 || mountPath.contains("Data")) {60 continue;61 }62 File mountRoot = new File(mountPath);63 if (!mountRoot.exists() || !mountRoot.isDirectory()64 || !mountRoot.canWrite()) {65 continue;66 }67 boolean equalsToPrimarySD = mountPath.equals(extFile68 .getAbsolutePath());69 if (equalsToPrimarySD) {70 continue;71 }72 paths.add(mountPath);73 }74 } catch (IOException e) {75 // TODO Auto-generated catch block76 e.printStackTrace();77 }78 return paths;79 }80 }
首先,我把它写成了一个工具类,因而声明了一个私有的构造器,目的就是要防止该类被实例化。
然后,首先获取了Android标准一部分的外置SD卡,如果它可用的话。
然后利用运行时,通过命令行函数"mount"来获取所有的存储位置,并对返回的结果进行SD卡或者TF卡的查找。
最后返回了所有可用于存储的不同的卡的位置,用一个List来保存。由于不是所有的手机都支持TF卡,因而这个List包含的路径未必很多,只有一个SD卡的手机只会返回一个路径,多个可用存储位置的会返回多个路径。
但有一点,是必须的,paths.get(0)肯定是内存位置或外置SD卡的位置的位置,因为它是primary external storage.
其他参考帖子:http://blog.csdn.net/androidwifi/article/details/17725989更多相关文章
- Android 监听U盘插入和拔出并获取U盘文件路径
- 2014.01.10 ——— android listview 记录和恢复位置
- Android百度地图默认位置中心点设置
- Android用属性动画拖动view到任意位置
- android 开发技巧(12)--更改 Toast 显示位置的技巧
- Android Studio编译动态替换清单文件AndroidManifest.xml内容(找