ファイル選択ってAndroid側で用意してくれてないんですよねー。かなり不便。

以下は、DT Homeで使ってるのを簡略化したものです。これを使えば、ファイラー(tetra filerなど)経由でファイルを選択してもらうことができます。ファイル選択を追加というか、ファイラーに投げるだけなんですけどね。僕の試した範囲では、アストロだとうまくいきませんが……まあだいたいのファイラーで使えるっぽいです。最新版のアストロでは正常に動作しました。ちょっと前のバージョンのバグだったみたいですね。

PreferenceActivityから使う場合はこんな感じ。

<!-- pref.xml -->
    <Preference android:title="test" >
        <intent
            android:action="@string/action_main"
            android:targetClass="@string/file_choose_class_name"
            android:targetPackage="@string/package_name" >
            <extra
                android:name="key"
                android:value="test" />
        </intent>
    </Preference>

「android:key=”test”」に当たるのが「android:value=”test”」の部分です。インテントを受け取って、その名前のキーにファイルパスを保存します。

package com.nagopy.home;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.widget.Toast;

public class FileChooseActivity extends Activity {
	private static final String FILE_TYPE = "file/*";

	private String targetKey;
	private boolean isNotInstalledFiler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		targetKey = getIntent().getExtras().getString("key");
		// 05/09訂正。指摘感謝です。やーこれは恥ずかしい……
		// if(targetKey == null || targetKey==""){
		if(targetKey == null || targetKey.equals(""){
			showToast("キーを設定してください。");
			finish();
			return;
		}

		Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
		intent.setType(FILE_TYPE);
		try {
			startActivityForResult(intent, 1);
		} catch (ActivityNotFoundException e) {
			showToast(R.string.filer_not_found);
			isNotInstalledFiler = true;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			String path = data.getData().getPath();
			// 後は適宜拡張子のチェックなどを行って、問題なければ保存するだけ
			showToast(path);
			getSP().edit().putString(targetKey, path).commit();

		} else {
			if (!isNotInstalledFiler) {
				showToast(R.string.cancel_filechoose);
			}
		}
		finish();
	}

	/**
	 * トースト表示
	 * @param text
	 */
	private void showToast(String text) {
		Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
	}

	/**
	 * リソースIDからトースト表示
	 * 本当は以下のURLを参考にして_(int resId)メソッドを作ると便利です
	 * http://d.hatena.ne.jp/language_and_engineering/20110815/p1
	 * @param resId
	 */
	private void showToast(int resId) {
		showToast(getText(resId).toString());
	}

	/**
	 * デフォルトのSharedPreferencesを返す
	 * 案外便利
	 * @return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
	 */
	private SharedPreferences getSP() {
		return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
	}
}

使う時はsp.getString(“key”,”")ってするだけです。

リソースとAndroidManifestを追加も忘れずに。

<!-- AndroidManifest.xml -->
    <activity
        android:name=".FileChooseActivity"
        android:theme="@android:style/Theme.Translucent" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
<!-- strings.xml -->
<string name="action_main">android.intent.action.MAIN</string>
<string name="package_name">com.nagopy.home</string>
<string name="file_choose_class_name">com.nagopy.home.FileChooseActivity</string>
<string name="filer_not_found">エラー:ファイラーが見つかりません。tetra filerなどのアプリをインストールしてください。</string>
<string name="cancel_filechoose">キャンセルしました。</string>