- Date: Tue 27 11 2012
- Category: Android
- Response: Comment 14 Trackback 0
外部ストレージのパスを取得する(Android 2.2~?)
【関連記事】外部SDカードについてまとめるまえのメモ
Androidでは、ストレージ(SDカードなど)のパスを取得するために Environment.getExternalStorageDirectory() が用意されています。
しかし、ストレージが内部ストレージ(取外不可)と外部ストレージ(取外可能)に別れている場合、内部ストレージを取得します。
外部ストレージを取得する Android API は用意されていません。
そこで開発者は色々な方法を使って、外部ストレージのパスを取得しています。
で、私も色々と試しました。こんな感じに。
×環境変数に登録されているパスを取得する
⇒ 環境変数がバラバラ。そもそもHTC端末など、一部の端末は登録されていない。
×環境変数と、一部特殊なパスは直書きで対応する
⇒ 種類が多すぎて対応しきれない
×シンボリックリンク参照
⇒ 設定されていないデバイスがある(そもそもこんなのに期待しては駄目…)
△マウントポイントから取得する(/proc/mounts)
⇒ マウントされていないと表示されない
○△システムの設定ファイルから取得する(/system/etc/vold/fstab)
⇒ Android2.2 (API 8 FROYO)以降からだが対応できそう(HTC J ISW13HT でのみ確認)
⇒ (2013/03/02) GalaxyNexus や一部のカスタムROMには存在しないため△にしました…
/system/etc/vold.fstab については、過去記事の『Android のファイルシステム設定ファイル(Android 2.2~?)』を見てください。
この /system/etc/vold.fstab を使ったファイルパスの取得方法は以下のとおり。
------------------------------------------------------------
2013/01/06 追記
Xperia VL SOL21 の場合、内部ストレージが fuse_mount に定義されているらしいので修正しました。
参考:hiroyuki_tの日記 - Androidで外部ストレージのパスを取得する方法
------------------------------------------------------------
/system/etc/vold.fstab には、ストレージのパスが全て設定されている(はず)ので、Environment.getExternalStorageDirectory()のパスも含まれています。
不要であれば各自で除外してください。
除外の仕方(例)
マウントされているか確認する場合は『デバイスにSDカードがマウントされているかチェックする(2)』で書いたメソッドを使ってチェックしてください。
ほかに /system/etc/vold.fstab を参照している人はいないかと調べてみたところ
wagic というマルチプラットフォームのカードゲームエンジンでも使われていました!(ほぼ同じことしてます)
https://code.google.com/p/wagic/source/browse/trunk/projects/mtg/Android/src/net/wagic/utils/StorageOptions.java
ゲームエンジンで使われているので信頼性は高そう!(主観)
こちらではパスに対して String#replaceAll(":.*$", "") しています。
必要なデバイスがあるということでしょうか…
とりあえずは無しで置いておきます。
Androidでは、ストレージ(SDカードなど)のパスを取得するために Environment.getExternalStorageDirectory() が用意されています。
しかし、ストレージが内部ストレージ(取外不可)と外部ストレージ(取外可能)に別れている場合、内部ストレージを取得します。
外部ストレージを取得する Android API は用意されていません。
そこで開発者は色々な方法を使って、外部ストレージのパスを取得しています。
で、私も色々と試しました。こんな感じに。
×環境変数に登録されているパスを取得する
⇒ 環境変数がバラバラ。そもそもHTC端末など、一部の端末は登録されていない。
×環境変数と、一部特殊なパスは直書きで対応する
⇒ 種類が多すぎて対応しきれない
×シンボリックリンク参照
⇒ 設定されていないデバイスがある(そもそもこんなのに期待しては駄目…)
△マウントポイントから取得する(/proc/mounts)
⇒ マウントされていないと表示されない
⇒ Android2.2 (API 8 FROYO)以降からだが対応できそう(HTC J ISW13HT でのみ確認)
⇒ (2013/03/02) GalaxyNexus や一部のカスタムROMには存在しないため△にしました…
/system/etc/vold.fstab については、過去記事の『Android のファイルシステム設定ファイル(Android 2.2~?)』を見てください。
この /system/etc/vold.fstab を使ったファイルパスの取得方法は以下のとおり。
------------------------------------------------------------
2013/01/06 追記
Xperia VL SOL21 の場合、内部ストレージが fuse_mount に定義されているらしいので修正しました。
参考:hiroyuki_tの日記 - Androidで外部ストレージのパスを取得する方法
------------------------------------------------------------
/**Android 2.1 (API 7 ECLAIR_MR1) 以下のエミュレータではファイルが存在しなかったので @TargetApi(Build.VERSION_CODES.FROYO) つけようかと思いましたが辞めておきました。
* ストレージのパスを取得する。
* ストレージがマウントされていなくてもパスを返します。
* ※ /system/etc/vold.fstab を参照しているため、Android 2.1 (API 7)以下の場合
* {@link java.io.FileNotFoundException} が発生する恐れがある。
*
* @return ストレージのパス一覧
*/
private List<String> getStoragePaths() {
List<String> mountList = new ArrayList<String>();
Scanner scanner = null;
try {
// マウント情報を取得する
scanner = new Scanner(new FileInputStream(new File(
"/system/etc/vold.fstab")));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("dev_mount") || line.startsWith("fuse_mount")) {
// dev_mount または fuse_mount のパスを登録する(同じパスは登録しない)
String path = line.replaceAll("\t", " ").split(" ")[2];
if (!mountList.contains(path))
mountList.add(path);
}
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} finally {
if (scanner != null) {
scanner.close();
}
}
return mountList;
}
/system/etc/vold.fstab には、ストレージのパスが全て設定されている(はず)ので、Environment.getExternalStorageDirectory()のパスも含まれています。
不要であれば各自で除外してください。
除外の仕方(例)
// ストレージのパス一覧を取得する
List<String> storageList = getStoragePaths();
// 内部ストレージを除外する
storageList.remove(Environment.getExternalStorageDirectory().getPath());
// Android2.3 (API 9) 以降であれば取りはずし可能かで判断できる
// if (!Environment.isExternalStorageRemovable()) {
// storageList.remove(Environment.getExternalStorageDirectory().getPath());
// }
マウントされているか確認する場合は『デバイスにSDカードがマウントされているかチェックする(2)』で書いたメソッドを使ってチェックしてください。
// ストレージのパス一覧を取得する
List<String> storageList = getStoragePaths();
// マウントされていないパスを除外する
for (int i = 0; i < storageList.size(); i++) {
if (!isMounted(storageList.get(i)))
storageList.remove(i--);
}
ほかに /system/etc/vold.fstab を参照している人はいないかと調べてみたところ
wagic というマルチプラットフォームのカードゲームエンジンでも使われていました!(ほぼ同じことしてます)
https://code.google.com/p/wagic/source/browse/trunk/projects/mtg/Android/src/net/wagic/utils/StorageOptions.java
ゲームエンジンで使われているので信頼性は高そう!(主観)
こちらではパスに対して String#replaceAll(":.*$", "") しています。
必要なデバイスがあるということでしょうか…
とりあえずは無しで置いておきます。
スポンサーサイト