Android カメラで撮影するかギャラリーから選択した画像をビューに表示してみる

Android カメラを起動して、ビューに表示してみる から応用というか、コードの付け足しで、カメラで写真を撮るか、ギャラリーから選択するのか、ダイアログを表示して、それぞれ内臓カメラと内臓ギャラリーアプリを利用してみました。

以下のコード中に特に明示しないプロパティ変数が出てきますが、前記事をベースに付け足したことを前提としているので、Android カメラを起動して、ビューに表示してみる  のコードも同時に参考にして頂ければ幸いです。

選択ダイアログ表示

AlertDialog に選択肢を表示して、タップされた選択肢で呼び出しを切り分けました。

public void picture(View v){
    //選択項目を準備する。
    String[] str_items = {"カメラで撮影", "ギャラリーから選択", "キャンセル"};
    new AlertDialog.Builder(this)
        .setTitle("選択")
        .setItems(str_items, new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int which) {
                switch(which){
                case 0:
                    wakeupCamera(); // カメラ起動
                    break;
                case 1:
                    wakeupGallery(); // ギャラリー起動
                    break;
                default:
                    // カメラ・ギャラリー以外(キャンセル)を想定
                    break;
                }
            }
        }
    ).show();
}

wakeupCamera / wakeupGallery メソッドは次に実装します。

picture は適当なボタンなどに割り当ててください。

カメラ起動

前回記事の内容と同じです。

protected void wakeupCamera(){
    File mediaStorageDir = new File(
        Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES
        ), "PictureSaveDir"
    );

    if(! mediaStorageDir.exists() & ! mediaStorageDir.mkdirs()) {
        Log.d("TAG", "Failed to create directory");
        return;
    }

    String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    bitmapFile = new File(mediaStorageDir.getPath() + File.separator + timeStamp + ".JPG");
    bitmapUri = Uri.fromFile(bitmapFile);

    Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    i.putExtra(MediaStore.EXTRA_OUTPUT, bitmapUri);
    startActivityForResult(i, REQUEST_CODE_CAMERA);
}

REQUEST_CODE_CAMERA は onActivityResult メソッド内で、カメラかギャラリーかを判別する起動コードです。

Activity クラスにクラス定数として宣言しています。

static protected int REQUEST_CODE_CAMERA  = 0x00000001;
static protected int REQUEST_CODE_GALLERY = 0x00000002;

別に16進数でなくともいいです。異なる整数値を割り当ててください。

ギャラリー起動

こちらは簡単です。setType で画像のみが表示されるようにフィルターをかけます。

protected void wakeupGallery() {
    Intent i = new Intent();
    i.setType("image/*");
    i.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(i, REQUEST_CODE_GALLERY);
}

同じく REQUEST_CODE_GALLERY は判別用コードです。

結果を受け取る

カメラまたはギャラリーアプリから戻ってきたときの requestCode によって処理を分岐します。

public void onActivityResult( int requestCode, int resultCode, Intent data ) {
    if(RESULT_OK == resultCode){
        if(null != bitmap){
            bitmap.recycle();
        }
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
        switch(requestCode){
            case 0x00000001:
                bitmap = BitmapFactory.decodeFile(bitmapUri.getPath(), options);

                // 撮影した画像をギャラリーのインデックスに追加されるようにスキャンさせる
                String[] paths = {bitmapUri.getPath()};
                String[] mimeTypes = {"image/*"};
                MediaScannerConnection.scanFile(
                    getApplicationContext(), paths, mimeTypes, new OnScanCompletedListener() {
                        @Override
                        public void onScanCompleted(String path, Uri uri) {
                        }
                    });
                break;
            case 0x00000002:
                try{
                    ContentResolver cr = getContentResolver();
                    String[] columns = { MediaStore.Images.Media.DATA };
                    Cursor c = cr.query(data.getData(), columns, null, null, null);
                    c.moveToFirst();
                    bitmapUri = Uri.fromFile(new File(c.getString(0)));

                    InputStream is = getContentResolver().openInputStream(data.getData());
                    bitmap = BitmapFactory.decodeStream(is, null, options);
                    is.close();
                }catch(Exception e){
                    e.printStackTrace();
                }
                break;
        }
        preview.setImageBitmap(bitmap);
    }
}

カメラで撮影したファイルを、ギャラリーのインデックスに読み込ませる処理が増えました。

これをやらないと、直前に撮影した画像をアプリ起動中にギャラリーから参照できませんでした。

(ギャラリーのインデックスが更新されるタイミングがあるようです。上記コードはそれを促します。)

どちらも最終的には bitmap を生成して、プレビュー用ガジェットへ画像を割り当てています。

public void photo(View v){
  //選択項目を準備する。
  String[] str_items = {"カメラで撮影", "ギャラリーから選択", "キャンセル"};
  new AlertDialog.Builder(this)
    .setTitle("選択")
    .setItems(str_items, new DialogInterface.OnClickListener(){
      public void onClick(DialogInterface dialog, int which){
        switch(which){
          case 0:
            wakeupCamera();
            break;
          case 1:
            wakeupGallery();
            break;
          default:
            break;
        }
      }
    }).show();
  }

シェアする

  • このエントリーをはてなブックマークに追加

フォローする