ContentProviderで端末内画像データを取得する


以前にTechBoosterでは、「ContentProviderからデータを取得する」においてContentProviderの使い方(Contact)を紹介しました。

本エントリでは、Mediaを管理するContentProviderから画像データを取得する方法を紹介していきます。

※詳細な説明の前に以下記事の内容を踏まえておくことをお勧めします。

また、SDカードの画像をContentProviderに登録するには以下記事が参考になります。

画像ファイルを取得する際の全体の流れは、以下の様になります。

  1. 画像ファイルにアクセスする為のレコードを取得する
  2. ID要素を用いて、Content URI を取得する

詳細は続きにて順に追っていきます。

1.画像ファイルにアクセスする為のレコードを取得する

ContentProviderからデータを取得する」の記事内容と同様に、Activity#managedQuery() からCursorを取得します。
Cursorの取得時に指定するURIには以下のどちらかを指定します。

端末内領域からの取得の場合 MediaStore.Images.Media.INTERNAL_CONTENT_URI
/sdcard からの取得の場合 MediaStore.Images.Media.EXTERNAL_CONTENT_URI

また、IDの取得に用いるCursor#getColumnIndex()の引数には、MeiaStore.Images.Media._IDを指定します。

	// Cursorの取得
	Cursor cursor = managedQuery(
			MediaStore.Images.Media.EXTERNAL_CONTENT_URI, //The URI of the content provider to query
			null, //List of columns to return.
			null, //SQL WHERE clause.
			null, //The arguments to selection, if any's are present
			null //SQL ORDER BY clause.
		);
	// Cursorを先頭へ移動
	cursor.moveToFirst();
	int fieldIndex = cursor.getColumnIndex(MediaStore.Images.Media._ID);
	Long id = cursor.getLong(fieldIndex);

2.取得したIDを用いて、BitmapデータのContent URI を取得する

ContentUris#withAppendedId()に指定するURIには、「1.画像ファイルにアクセスする為のレコードを取得する」で表に纏めた内のいずれかを指定します。
作成したURIを元に、MediaStore.Images.Media.getBitmap()メソッドを用いてBitmapデータを取得します。

	Uri bmpUri = ContentUris.withAppendedId(
			MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
	Bitmap bmp = MediaStore.Images.Media
			.getBitmap(getContentResolver(), bmpUri);
Androidのカメラ画像はJPEGだよね!MediaStore.Images.Media.getBitmap()メソッドは中でBitmapFactory.decodeStream()を呼び出してるんだ。元ファイルはJPEGだったとしても、Bitmap型にして取り出せるんだね!

今回のサンプル

今回は、本エントリで紹介した「ContentProviderで端末内画像データを取得する」の内容を踏まえて、
端末「/sdcard」内のデータをGridViewを用いて表示するサンプルを作成しました。
以下にサンプルコードを添付します。
ご参考程度にどうぞ。

public class MainSample extends Activity {
	GridView mGrid;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		//レコードの取得
		Cursor cursor = managedQuery(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,
				null);

		cursor.moveToFirst();

		// init for loop
		int fieldIndex;
		Long id;
		int cnt = 0, VolMax = 0;
		HashMap<Integer, Uri> uriMap = new HashMap<Integer, Uri>(); //URIをMapで管理する

		do {
			//カラムIDの取得
			fieldIndex = cursor.getColumnIndex(MediaStore.Images.Media._ID);
			id = cursor.getLong(fieldIndex);

			//IDからURIを取得
			Uri bmpUri = ContentUris.withAppendedId(
					MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
			uriMap.put(cnt, bmpUri);
			cnt++;
		} while (cursor.moveToNext());

		VolMax = --cnt;
		cnt = 0;

		/* Setting GridView */
		mGrid = (GridView) findViewById(R.id.myGrid);
		mGrid.setAdapter(new myAdapter(getContentResolver(), uriMap, VolMax));
	}

	// GridView用のCustomAdapter
	//
	public class myAdapter extends BaseAdapter {
		private ContentResolver cr;
		private HashMap<Integer, Uri> hm;
		private int MAX;
		private Bitmap tmpBmp;
		ImageView imageView;

		public myAdapter(ContentResolver _cr, HashMap<Integer, Uri> _hm, int max) {
			cr = _cr;
			hm = _hm;
			// MAX = max;
			MAX = 30;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				imageView = new ImageView(MainSample.this);
				imageView.setLayoutParams(new GridView.LayoutParams(100, 100));
			} else {
				imageView = (ImageView) convertView;
			}

			try {
				tmpBmp = MediaStore.Images.Media
						.getBitmap(cr, hm.get(position));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			imageView.setImageBitmap(tmpBmp);

			return imageView;
		}

		public final int getCount() {
			return MAX;
		}

		public final Object getItem(int position) {
			return position;
		}

		public final long getItemId(int position) {
			return position;
		}
	}
}
One Comment