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: 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.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 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.