たとえば以下のようなCursorLoader
を継承したクラスを作った時に、CursorLoaderのコンストラクタの引数にどんな風にSQLを渡せばいいのかよくわかんなかったので調べました。
GalleryLoader.java
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のコンストラクタを見てもらえればわかります。
CursorLoader.java
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");
}
と書き直しました。
これで期待通りの挙動になっています。