Furudateのブログ

プログラミングやネットワーク系の知識・技術がメインのブログ。技術メモ帳的な感じになるかと。岩手から発信していきます。

【Android】カメラかギャラリーを選択してビューに表示

おはようございます。


今回は、Androidでカメラ撮影かギャラリーから写真を選ぶかを選択して、イメージビューに表示することをしたいと思います。

前準備

前準備として、Manifestにパーミッションを追加します。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" android:required="false" />


また、クラス変数として、一番最初に以下の変数を宣言します。

static final int REQUEST_CODE_CAMERA = 1; /* カメラを判定するコード */
static final int REQUEST_CODE_GALLERY = 2; /* ギャラリーを判定するコード */
	
private Bitmap bm;
private Uri bitmapUri;

上からカメラの利用、外部ストレージの書き込み、音声録音の許可を求めます。一番下はアプリがカメラを使用できても、それが必須でない場合にFalseをセットする。


カメラかギャラリーかを選択するAlert Dialogを作成し、表示

// アップロードボタンが押された時
String[] str_items = {"カメラで撮影", "ギャラリーの選択", "キャンセル"};
	new AlertDialog.Builder(this)
	.setTitle("写真をアップロード")
	.setItems(str_items, new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {
			// TODO 自動生成されたメソッド・スタブ
			switch(which){
				case 0:
					wakeupCamera(); // カメラ起動
					break;
				case 1:
					wakeupGallery(); // ギャラリー起動
					break;
				default:
					// キャンセルを選んだ場合
					break;
						}
			}
	}).show();

カメラ起動の処理

  • Environment.getExternalStoragePublicDirectory でピクチャーのパスを取得し、書き込む
protected void wakeupCamera(){
	File mediaStorageDir = new File(
		Environment.getExternalStoragePublicDirectory(
			Environment.DIRECTORY_PICTURES
		), "PictureSaveDir"
	);
	if (! mediaStorageDir.exists() & ! mediaStorageDir.mkdir()){
		return;
	}
	String timeStamp = new SimpleDateFormat("yyyMMddHHmmss").format(new Date());
	File mediaFile;
	mediaFile = new File(mediaStorageDir.getPath() + File.separator + timeStamp + ".JPG");
	Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
	bitmapUri = Uri.fromFile(mediaFile);
	i.putExtra(MediaStore.EXTRA_OUTPUT, bitmapUri); // 画像をmediaUriに書き込み
	startActivityForResult(i, REQUEST_CODE_CAMERA);
}

ギャラリー起動の処理

protected void wakeupGallery(){
	Intent i = new Intent();
	i.setType("image/*"); // 画像のみが表示されるようにフィルターをかける
	i.setAction(Intent.ACTION_GET_CONTENT); // 出0他を取得するアプリをすべて開く
	startActivityForResult(i, REQUEST_CODE_GALLERY);
}

カメラまたはギャラリーから戻ってきた時の処理

  • requestCodeによって分岐
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
	if (resultCode == RESULT_OK){
		if (bm != null)
			bm.recycle(); // 直前のBitmapが読み込まれていたら開放する
		
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 4; // 元の1/4サイズでbitmap取得
		
		switch(requestCode){
			case 1: // カメラの場合
				bm = 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 2: // ギャラリーの場合
				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());
					bm = BitmapFactory.decodeStream(is, null, options);
					is.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			break;
		}
		imgView.setImageBitmap(bm); // imgView(イメージビュー)を準備しておく
	}
}

以上です。
これでイメージビューに写真を表示することができました!


それでは。