Bootstrap

android 手机获取外置SD卡路径

一部分手机将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“,在其他手机就有可能返回:“mounted

原因已经知道了,可是如何在无外置SD卡的时候,获取到这个内置eMMC存储的具体路径呢?

既然使用 Environment.getExternalStorageDirectory() 获取到的是外置SD卡路径,但是我又没有插入SD卡,这个时候我想使用内置的eMMC存储来存储一些程序中用到的数据,我怎么去获取这个eMMC存储的路径呢?

答案是:通过扫描系统文件"system/etc/vold.fstab”来实现。

"system/etc/vold.fstab” 只是一个简单的配置文件,它描述了Android的挂载点信息。
我们可以遍历这个文件来获取所有的挂载点:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     /**
      * 遍历 "system/etc/vold.fstab” 文件,获取全部的Android的挂载点信息
     
      * @return
      */
     private  static  ArrayList<String> getDevMountList() {
         String[] toSearch = FileUtils.readFile( "/etc/vold.fstab" ).split( " " );
         ArrayList<String> out =  new  ArrayList<String>();
         for  ( int  i =  0 ; i < toSearch.length; i++) {
             if  (toSearch[i].contains( "dev_mount" )) {
                 if  ( new  File(toSearch[i +  2 ]).exists()) {
                     out.add(toSearch[i +  2 ]);
                 }
             }
         }
         return  out;
     }


之后,当 Environment.getExternalStorageState()返回“removed”的时候(即,当没有挂载外置SD卡的时候),通过getDevMountList()方法获取一个list,这个list中可以进行写操作的那个就是系统自带的eMMC存储目录了。

判断逻辑:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
     /**
      * 获取扩展SD卡存储目录
     
      * 如果有外接的SD卡,并且已挂载,则返回这个外置SD卡目录
      * 否则:返回内置SD卡目录
     
      * @return
      */
     public  static  String getExternalSdCardPath() {
 
         if  (SDCardUtils.isMounted()) {
             File sdCardFile =  new  File(Environment.getExternalStorageDirectory().getAbsolutePath());
             return  sdCardFile.getAbsolutePath();
         }
 
         String path =  null ;
 
         File sdCardFile =  null ;
 
         ArrayList<String> devMountList = getDevMountList();
 
         for  (String devMount : devMountList) {
             File file =  new  File(devMount);
 
             if  (file.isDirectory() && file.canWrite()) {
                 path = file.getAbsolutePath();
 
                 String timeStamp =  new  SimpleDateFormat( "ddMMyyyy_HHmmss" ).format( new  Date());
                 File testWritable =  new  File(path,  "test_"  + timeStamp);
 
                 if  (testWritable.mkdirs()) {
                     testWritable.delete();
                 else  {
                     path =  null ;
                 }
             }
         }
 
         if  (path !=  null ) {
             sdCardFile =  new  File(path);
             return  sdCardFile.getAbsolutePath();
         }
 
         return  null ;
     }
;