fc2ブログ

戌印-INUJIRUSHI- (Androidあれこれ)

Androidのプログラミングをメインにしてます。記事に貼られたソースコードはダブルクリックすることで行番号をはずしてコピーすることができます。

 
1
2
3
4
5
6
8
9
11
12
13
14
15
16
18
19
20
22
23
28
29
30
11

外部ストレージのパスを取得する(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 を参照しているため、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;
}
Android 2.1 (API 7 ECLAIR_MR1) 以下のエミュレータではファイルが存在しなかったので @TargetApi(Build.VERSION_CODES.FROYO) つけようかと思いましたが辞めておきました。

/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(":.*$", "") しています。
必要なデバイスがあるということでしょうか…
とりあえずは無しで置いておきます。
スポンサーサイト



プロフィール

とむ・やむくん

Author:とむ・やむくん
管理人について

Windows 7 / 64bit
Eclipse 4.2 Juno (日本語パッチ済)

スポンサーサイト
最新トラックバック
検索フォーム
ブロとも申請フォーム
QRコード
QR
Twitter
2013/01/04 19:00 カウント開始