Android中获取文件存储位置(内部存储或者扩展SD卡)

43 篇文章 0 订阅
我们通常用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卡的情况下,在中兴手机或者三星上,调用

打印 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: getExtSDCardPaths
10      * @Description: to obtain storage paths, the first path is theoretically
11      *               the returned value of
12      *               Environment.getExternalStorageDirectory(), namely the
13      *               primary external storage. It can be the storage of internal
14      *               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 of
17      *               external sdcard. Additionally, the paths is directory.
18      * @return List<String>
19      * @throws IOException
20      */
21     public static List<String> getExtSDCardPaths() {
22         List<String> paths = new ArrayList<String>();
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 judge
32             // whether tfCard exists by the result
33             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/fuse
42                 if ((!line.contains("fat") && !line.contains("fuse") && !line
43                         .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(extFile
68                         .getAbsolutePath());
69                 if (equalsToPrimarySD) {
70                     continue;
71                 }
72                 paths.add(mountPath);
73             }
74         } catch (IOException e) {
75             // TODO Auto-generated catch block
76             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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值