SiteMap

2014年4月26日土曜日

Android - SD Card

在 4.0 後,
Environment.getExternalStorageDirectory().getAbsolutePath();
得到的是內建的儲存空間

因為有些機種可以外接SD卡, 有些不行, 而 Android 沒有提供取得外接SD卡的方法,


不過這些資訊放在 system/etc/vold.fstab 裡面, 

vold.fstab 本質上是個 txt 檔案, 所以打開來看看
就知道外接SD卡在哪了.打開後找到:

# internal sdcard
dev_mount sdcard /mnt/sdcard 1 /devices/platform/....../mnc0

# external sdcard
dev_mount emmc /mnt/emmc auto /devices/platform/....../mnc2

上面是 cmd 的指令

dev_mount      掛載裝置
sdcard            掛載之後捷徑命名為 sdcard
/mnt/sdcard     捷徑連結到的實體路徑是 /mnt/sdcard 
                     ( 最前面多了個 "/" 表示從根目錄開始 )
/decives/platform/..../mnc0    實際上進入該路徑到達的是裝置 mnc0

想當然我們的外接 SDcard 在# external sdcard 這行下面


接下來就簡單了, 程式讀到 external sdcard 這行後
下一行用空格分割把第三個字串取出, 記得先 trim()
( String trim(), 回傳去除首尾空白符號的子字串 )

if( "# external sdcard".equal(readVoldBufferRead.readline()) ) {
      externalSDcardPath = readVoldBufferRead.readline().trim().split(" ")[2];
}

但是上面這是有特地註解 external sdcard 的情況下才有效.

所以也可以用 dev_mount 來分析
如果每次遇到的dev_mount 該行所得到的路徑與
Environment.getExternalStorageDirectory().getAbsolutePath(); 
不一樣的話, 我們就可以認為這是其他儲存裝置的路徑了吧

String eachLine = readVoldBufferRead.readline().trim();
if( eachLine.indexOf("dev_mount") != -1 ) {
      externalSDcardPath = eachLine.split(" ")[2];
}

如果我們想要讀取或者向SD卡寫入,這時就必須先要判斷一個SD卡的狀態,否則有可能出錯。
那麼SD卡狀態為什麼時才能讀取呢,經過我的各種情況的實踐,大致如下:

SD狀態
現象描述
/mnt/sdcard目錄是否存在
canRead返回
canWrite返回
在/mnt/sdcard創建文件
在/mnt/sdcard創建文件夾
MEDIA_MOUNTED
SD卡正常掛載
TRUE
TRUE
TRUE
TRUE
TRUE
MEDIA_REMOVED
無介質
TRUE
FALSE
FALSE
false:  原因Permission denied
FALSE
MEDIA_UNMOUNTED
有介質,未掛載,在系統中刪除
TRUE
FALSE
FALSE
false:  原因Permission denied
FALSE
MEDIA_BAD_REMOVAL
介質在掛載前被移除,直接取出SD卡
TRUE
FALSE
FALSE
false:  原因Permission denied
FALSE
MEDIA_CHECKING
正在磁盤檢查,剛裝上SD卡時
TRUE
FALSE
FALSE
false:  原因Permission denied
FALSE
MEDIA_SHARED
SD卡存在但沒有掛載,並且通過USB大容量存儲共享,操作打開USB存儲
TRUE
FALSE
FALSE
false:  原因Permission denied
FALSE
MEDIA_MOUNTED_READ_ONLY
sd卡存在並且已掛載,但是掛載方式為只讀
-
-
無法模擬,SD卡不允許修改權限
MEDIA_NOFS
介質存在但是為空白或用在不支持的文件系統
-
-
無法模擬,SD卡格式化後再加載會自動生成系統文件
MEDIA_UNMOUNTABLE
存在SD卡但是不能掛載,例如發生在介質損壞
-
-
無法模擬



通過上表可以看出,只有在SD卡狀態為MEDIA_MOUNTED時/mnt/sdcard目錄才是可讀可寫,並且可以創建目錄及文件。
所以我們讀取SD卡時一般會這麼寫:

String state;
String path;
state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)){
path = Environment.getExternalStorageDirectory().getAbsolutePath();
}


讀寫SD卡記得加這兩個權限:

 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

0 件のコメント: