kakueki61's dev history

備忘録的に記録を残しています

【Android】CursorLoaderのSQLに関して

たとえば以下のような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;
    }

ContentResolver.query())

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");
    }

と書き直しました。 これで期待通りの挙動になっています。