首页 > 代码库 > Android手机外置SD卡(TF卡)的获取方法

Android手机外置SD卡(TF卡)的获取方法

Android手机上的外置SD卡,起初的时候,即在Android出世的前几年,那时手机的存储是十分有限的,不像现在到处可见16G、32G和64G的存储,因而那时候的手机有的厂商允许插入外置的SD卡,此时这张卡仍处于手机的扩展部分。后来,随着手机的发展以及存储能力的增加,这张外置SD卡,逐渐成为了手机的一部分,不再允许可挺拔了,当然现在依然有的手机允许对存储进行拓展,比如三星等。

那张拓展的存储卡,现在叫做TF卡,且不是所有的手机都支持它,但是有时候有些奇葩需求偏要优先存储在TF卡里面,这叫不得不要求开发人员去检查这张卡是否存在、是否可用。又因为这是手机厂商可拓展、可自定义的部分,所有不同厂商生产的手机,以及同一厂商生产的不同型号的手机,TF卡的位置都相差很大,并没有一个统一的名称或位置。因而这是比较困难的一部分,但是还好Android是开源的,我们可以通过运行时来判断手机是否有TF卡,以及TF卡是否可用。

下面这个方法可以获取手机的可以存储,包括SD卡、TF卡等,对多存储卡进行了匹配,详细的代码如下:

 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 List<String>19      * @throws IOException20      */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.endsWith(Environment.MEDIA_UNMOUNTED)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 }
View Code

首先,我把它写成了一个工具类,因而声明了一个私有的构造器,目的就是要防止该类被实例化。

然后,首先获取了Android标准一部分的外置SD卡,如果它可用的话。

然后利用运行时,通过命令行函数"mount"来获取所有的存储位置,并对返回的结果进行SD卡或者TF卡的查找。

最后返回了所有可用于存储的不同的卡的位置,用一个List来保存。由于不是所有的手机都支持TF卡,因而这个List包含的路径未必很多,只有一个SD卡的手机只会返回一个路径,多个可用存储位置的会返回多个路径。

但有一点,是必须的,paths.get(0)肯定是外置SD卡的位置,因为它是primary external storage.