たとえば以下のようなCursorLoader
を継承したクラスを作った時に、CursorLoaderのコンストラクタの引数にどんな風にSQLを渡せばいいのかよくわかんなかったので調べました。
public class GalleryLoader extends CursorLoader{ private static final String[] PROJECTION = { MediaStore.Images.Media.BUCKET_ID }; private static final 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; public GalleryLoader(Context context) { super(context, MediaStore.Files.getContentUri("external"), PROJECTION, SELECTION, null, MediaStore.Files.FileColumns.DATE_ADDED + " DESC"); } @Override public Cursor loadInBackground() { return super.loadInBackground(); } }
これはローカルの端末のリソースから画像と動画を取り出すためのものですが、その中でも"アルバム"を取得しようとしている部分です。
やりたいこととしては、GROUP BY
句を入れるということです。
なぜならこのままだとリソースの数分だけレコードが返ってしまう。まずはアルバムだけ取得したいという感じです。
問題点としては、CursorLoaderのコンストラクタを見てもらえればわかります。
public CursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { super(context); mObserver = new ForceLoadContentObserver(); mUri = uri; mProjection = projection; mSelection = selection; mSelectionArgs = selectionArgs; mSortOrder = sortOrder; }
Where
句に渡す引数はあるんですが、GROUP BY
をどうやって挿入すればいいのかわからない。
ということで実際にどのようなSQLが発行されているのか見てみました。 私が書いたようなGalleryLoaderでは以下のようなSQLが発行されていました。
SELECT bucket_id FROM files WHERE ( alive=1 ) AND (media_type=1 OR media_type=3) ORDER BY date_added DESC
ここに無理やりGROUP BY
を挿入しようとすると、WHERE
にうまいこと渡してやればよさそうです。
というわけで、
private static final String GROUP_BY = ") GROUP BY " + MediaStore.Images.Media.BUCKET_ID + ", (2";
といった感じにして
public GalleryLoader(Context context) { super(context, MediaStore.Files.getContentUri("external"), PROJECTION, SELECTION + GROUP_BY, null, MediaStore.Files.FileColumns.DATE_ADDED + " DESC"); }
と書き直しました。 これで期待通りの挙動になっています。