LoginSignup
69
66

More than 5 years have passed since last update.

超ラクチンに端末の画像を複数選択するためのライブラリを作った話

Last updated at Posted at 2014-03-28

Android の端末に保存されている画像を、アルバム(ディレクトリ)を跨って複数枚選択するためのライブラリを作りました。

Intent の Action による画像選択の問題

Intent.ACTION_PICKIntent.ACTION_GET_CONTENT を用いれば、ギャラリーアプリや KitKat のファイルセレクタが立ち上がって、使いたい画像を選択することができます。

ただし、この方法では、画像を 1 枚しか選択できないため、複数枚を同時に取り扱おうとすると、ユーザに何度も選択画面との往来をさせてしまいます。

一方で、Intent.ACTION_SEND_MULTIPLE という Action も宣言されており、ギャラリーアプリなどで複数選択して共有ボタンを押すと、この Action で Intent が発火され、選択した複数の画像 Uri が取得できます。

しかし、ギャラリーアプリからの共有 Intent では、複数のアルバム(ディレクトリ)から一部の写真だけをピックアップしてくる、という使い方ができません。

また、アプリを使用するコンテキストで、ギャラリーアプリから選択して目的のアプリを立ち上げるという動作を説明するのは難易度が高かったりします。

このライブラリが目指したもの

まず、アプリに組み込んで使えること、そして、複数のアルバムから一部をピックアップして、複数の写真を選択することを達成できることが、このライブラリの目指したところです。

そしてなにより、単純な API で使用できることも重要でした。

動作する様子

リポジトリには、サンプルアプリも同封されています。

ライブラリの機能を呼び出すと、以下の様な、すべての写真一覧が表示されます。

device-2014-03-28-162335.png

画像と、画像にオーバレイする形でチェックボックスが表示され、チェックマークをつけると選択したことになります。

アルバムの絞込は、NavigationDrawer で行います。

device-2014-03-28-162413.png

端末内で MediaStore が知っている Bucket 毎にアルバムがわかれています。

画像の選択状態は、アルバムを切り替えても保存されています。
そこで、全体でどの写真を選んだかを見るためのビューも用意してあります。

device-2014-03-28-162626.png

これで、アクションバーの完了ボタンを押すと、選択した画像の Uri が、呼び出した Activity の onActivityResult に渡されます。

使い方

API の呼び出しは、Picasso とよく似た手順で行います。


public class SomeActivity extends Activity {
  public static final int REQUEST_CODE_CHOOSE = 1;

  public void onClickButton(View view) {
    // call chooser on click button like this
    Laevatein.from(this).choose(MimeType.of(MimeType.JPEG)).forResult(REQUEST_CODE_CHOOSE);
  }
}

これで選択画面が立ち上がります。

選択が終わったら、以下のようにして結果を取り出します。


public class SomeActivity extends Activity {
  public static final int REQUEST_CODE_CHOOSE = 1;

  @Override
  protected void onActivityResult(int requestCode, int resultcode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
    case REQUEST_CODE_CHOOSE:
      if (resultCode == RESULT_OK) {
        // Get result and proceed your work from here...
        List<Uri> selected = Laevatein.obtainResult(data);
      }
      break;
    default:
      break;
    }
  }
}

カスタマイズ

基本的に、テーマは全てアプリの持つテーマに合わせられます。ですので、ActionBar の装飾だったり、チェックボックスのスタイルだったりは、ライブラリ用に特別な実装を必要としません。

画像一覧のセルの見た目を変更したい場合は、以下のようにします。


Laevatein.from(this).choose(MimeType.of(MimeType.JPEG))
        .bindEachImageWith(R.layout.hoge, R.id.image_view_id, R.id.checkbox_id)
        .forResult(1);

選択できる画像について、制限のある仕様を設定したい場合、以下の様な API が提供されています。


Laevatein.from(this).choose(MimeType.of(MimeType.JPEG))
        .count(0, 100) // 選べる数を 0 ~ 100 枚に制限
        .quality(10, 10000) // 選べる画像の画質を、ピクセルサイズで 10px から 10000px に制限
        .forResult(1);

選択している最中に写真をとって、それを選択状態にしておきたい場合は以下のようにします。


Laevatein.from(this).choose(MimeType.of(MimeType.JPEG))
        .capture(true)
        .forResult(1);

選び終わった後に、選択をやり直したい場合は、以下のようにします。


List<Uri> list; // 選択したものを保持するリスト

Laevatein.from(this).choose(MimeType.of(MimeType.JPEG))
        .resume(list)
        .forResult(1);

Picasso のようにメソッドをつなげることで、様々な組み合わせで API を呼び出し、仕様を設定することができます。

今後の展望

KitKat で登場したファイルセレクタの利点は、ドキュメントプロバイダを持っているアプリからのデータのインポートが出来る点にあります。これをこのライブラリでも取り扱うことが出来るようになれば、Dropbox などからも画像を選択できるようになり、より便利に使える様になると思います。

コントリビュート

Issue を立てて修正を依頼していただくか、Pull Request で差分を投げていただくかで、コントリビュートしていただけます。

69
66
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69
66