kkAyatakaのメモ帳。

誰かの役に立つかもしれない備忘録。

ギャラリーで写真を選択して結果を受け取る

Androidで写真を選択する場合、他のアプリ(通常は標準のギャラリー)を起動して、選択結果を受け取るのが簡単です。

この操作は抽象化すると、「アクティビティを起動し結果を受け取る」ということになるので、ドキュメントもその部分を参考にします。

リファレンス

アクティビティの実行も、結果の取得もIntentが主役になるので、Intentのリファレンスも確認します。

アクティビティの実行

リファレンスを参考にIntentを生成して、startActivityForResultに渡します。ポイントはsetTypeでコンテンツのMIMEタイプを指定する部分でしょうか。サンプルでは「Phone.CONTENT_TYPE」となっているので、同系統で「MediaStore.Images.Media.CONTENT_TYPE」を指定しておきます。

MIMEタイプは「image/*」などでも動作します。手持ちの環境では動作に違いが出ませんでしたが、結果取得時に意味があいまいになるので定数を利用したほうが良いと考えています(細かいところは理解不足)。

startActivityForResultの第2引数は、結果取得時に何のリクエストの結果であるかを判定するための値です。今回のようにリクエストが1つであれば使用することは無いので、適当に値を渡しても問題ありませんね。

static final int PICK_IMAGE_REQUEST = 1;

private void pickImage() {
  Intent intent = new Intent(Intent.ACTION_PICK);
  intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
  startActivityForResult(intent, PICK_IMAGE_REQUEST);
}

結果の取得

startActivityForResultの結果はonActivityResultにて取得できるので、オーバーライドして処理します。startActivityForResultの第2引数で渡した値(requestCode)と、選択の結果(resultCode)を判定し、dataにアクセスします。

dataでアクセス可能なものは実行時のActionに依存するようです。IntentのACTION_PICKの記述を参照すると、URIが返るとのことなので、getDataでURIを取得します。

URI取得後は、ContentResolverにアクセスして必要なデータを取得します。ここではファイルパスを取得しています。アクセスできるデータは画像の場合、MediaStore.Imagesあたりを参照。アルバム名などいろいろなデータが取得できるほか、サムネイルも準備されています。

@Override
protected void onActivityResult(int requestCode,
                                int resultCode,
                                Intent data) {
  if (requestCode == PICK_IMAGE_REQUEST) {
    if (resultCode == RESULT_OK) {
      String[] projection = {Media.DATA};
      Cursor cur = getContentResolver().query(data.getData(),
                                              projection,
                                              null, null, null);
      cur.moveToNext();
      Log.d("ImagePick", cur.getString(0));
    }
  }
}