android開發中擷取手機上可用SD卡方法分享

來源:互聯網
上載者:User

現在的android手機型號複雜多樣,造成了開發過程中使用官方的擷取sd卡的方法在部分的手機上並不適用,所以需要進行開發的自己封裝,以下就是代碼,希望分享出來,大家共同學習

/**
* 擷取手機sd卡的工具類
* @author wy
*/
public class SDCardUtils {
/*
* avoid initializations of tool classes
*/
private SDCardUtils() {
// TODO Auto-generated constructor stub
}

/**
* @Title: getExtSDCardPaths
* @Description: to obtain storage paths, the first path is theoretically
* the returned value of
* Environment.getExternalStorageDirectory(), namely the
* primary external storage. It can be the storage of internal
* device, or that of external sdcard. If paths.size() >1,
* basically, the current device contains two type of storage:
* one is the storage of the device itself, one is that of
* external sdcard. Additionally, the paths is directory.
* @return List<String>
* @throws IOException
* 擷取手機上所有可用的sd卡路徑
* @return
*/
public static ArrayList<String> getExtSDCardPaths() {
ArrayList<String> paths = new ArrayList<String>();
String extFileStatus = Environment.getExternalStorageState();
File extFile = Environment.getExternalStorageDirectory();
if (extFileStatus.equals(Environment.MEDIA_MOUNTED) && extFile.exists()
&& extFile.isDirectory()) {
paths.add(extFile.getAbsolutePath());
}
try {
// obtain executed result of command line code of 'mount', to judge
// whether tfCard exists by the result
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("mount");
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
int mountPathIndex = 1;
while ((line = br.readLine()) != null) {
// format of sdcard file system: vfat/fuse
if ((!line.contains("fat") && !line.contains("fuse") && !line
.contains("storage"))
|| line.contains("secure")
|| line.contains("asec")
|| line.contains("firmware")
|| line.contains("shell")
|| line.contains("obb")
|| line.contains("legacy") || line.contains("data")) {
continue;
}
String[] parts = line.split(" ");
int length = parts.length;
if (mountPathIndex >= length) {
continue;
}
String mountPath = parts[mountPathIndex];
if (!mountPath.contains("/") || mountPath.contains("data")
|| mountPath.contains("Data")) {
continue;
}
File mountRoot = new File(mountPath);
if (!mountRoot.exists() || !mountRoot.isDirectory()) {
continue;
}
boolean equalsToPrimarySD = mountPath.equals(extFile
.getAbsolutePath());
if (equalsToPrimarySD) {
continue;
}
paths.add(mountPath);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return paths;
}

/**
* SD卡剩餘空間大小
* @param path 取得SD卡檔案路徑
* @return 單位MB
*/
public static long getSDFreeSize(String path) {
StatFs sf = new StatFs(path);
// 擷取單個資料區塊的大小(Byte)
long blockSize = sf.getBlockSize();
// 閒置資料區塊的數量
long freeBlocks = sf.getAvailableBlocks();
// 返回SD卡空閑大小
return (freeBlocks * blockSize) / 1024 / 1024; //
}

/**
* SD卡總容量
* @param path 取得SD卡檔案路徑
* @return 單位MB
*/
public static long getSDAllSize(String path) {
StatFs sf = new StatFs(path);
// 擷取單個資料區塊的大小(Byte)
long blockSize = sf.getBlockSize();
// 擷取所有資料區塊數
long allBlocks = sf.getBlockCount();
// 返回SD卡大小
// return allBlocks * blockSize; //單位Byte
// return (allBlocks * blockSize)/1024; //單位KB
return (allBlocks * blockSize) / 1024 / 1024;
}

/**
* 判斷當前記憶卡是否可用
* @param mContext
* @return
*/
public static final boolean isExist(String sdPath) {
ArrayList<String> list = getExtSDCardPaths();
for (int i = 0; i < list.size(); i++) {
if(list.contains(sdPath)) {
return true;
}
}
return false;
}
}


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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.