Android端末内の画像や動画、音楽ファイルの一覧を取得する方法について

f:id:moshimore:20170715041846j:plain
先日のタイムスタンプ変更アプリを開発する際にAndroid端末内の画像や動画、音楽ファイルの一覧を取得する方法を調べました。
わざわざ端末内のファイルをくまなく検索しなくても、Androidには簡単に一覧を取得する仕組みが用意されていていました。
knowledge.moshimore.jp


取得する方法

AndroidにはContentResolverと言う仕組みが用意されていて、そこからファイルの一覧を取得できます。
SQLのようなイメージで操作して取得することができます。

検索方法の指定

uriには検索対象のURIを指定します。”external”にすれば全般的なファイルを対象とすることができます。→FROM
projectionには検索結果で取得する項目名を指定します。→SELECT
selectionには検索条件を指定します。→WHERE
sortOrderにはソート条件を指定します。→ORDER BY

Uri uri = MediaStore.Files.getContentUri("external");
String[] projection = {
MediaStore.Files.FileColumns.MEDIA_TYPE,
MediaStore.Files.FileColumns.MIME_TYPE,
MediaStore.Files.FileColumns.DATA
};
String selection =
MediaStore.Files.FileColumns.MEDIA_TYPE + "=" + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE +
" OR " +
MediaStore.Files.FileColumns.MEDIA_TYPE + "=" + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
String sortOrder = MediaStore.Files.FileColumns.DATA + " ASC";

検索と結果の取得

クエリーを発行してカーソルからデータを1行ずつ取得していくイメージです。
途中にあるgetColumnIndexでは、項目(列)のインデックスを予め取得しておいて、行ごとのデータを取り出す際にそのインデックス(=列番号)を指定します。

ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(uri, projection, selection, null, sortOrder);
int mediaTypeIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.MEDIA_TYPE);
int mimeTypeIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE);
int dataIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
cursor.moveToFirst();
while (!cursor.isAfterLast())
{
String mediaType = cursor.getString(mediaTypeIndex);
String mimeType = cursor.getString(mimeTypeIndex);
String data = cursor.getString(dataIndex);
cursor.moveToNext();
}
cursor.close();

まとめ

なぜ、TwitterやInstagramが、カメラで直近で撮影したデータを素早く端末内から検索できるのか不思議に思っていました。
今回のContentResolverの仕組みを知ることで、その点を解決できました。

以上、Android端末内の画像や動画、音楽ファイルの一覧を取得する方法についてでした。