加入游标和排序

时间:2015-07-20 08:03:00

标签: android cursor mediastore

我正在写一个"画廊类型"适用于Android的应用。在"主要活动"中,我有一个GridView,我想从设备上的照片加载/填充缩略图。所以我编写了一个ContentProvider,查询方法从MediaStore.Media.Thumbnails返回一个游标。

但是,我还想从MediaStore.Media.Images中显示一些元数据。为了做到这一点,我最终使用CursorJoiner来加入ID上的c_thumbs和c_images。唯一的问题是,CursorJoiner要求输入游标已经按连接键(ID)按升序排序(排序)。我想要的是最新的照片,但有没有办法对现有的(已加载的)光标进行排序?

  
    

除了CursorJoiner,也许我可以在SQL中进行连接?是吗     可以加入MediaStore.Images.Media和     MediaStore.Images.Thumbnails在一个查询中(以及如何工作)?

  
     

Apparently, that's not possible

       // split projection into MediaStore and MediaStore.Thumbs parts
        ArrayList<String> MS_proj = new ArrayList<>();
        ArrayList<String> MS_proj_thumbs = new ArrayList<>();
        for (String f : projection) {
            if (PhotoContract.ThumbEntry.COL_TYPES.get(f).equals(PhotoContract.TARGET_MEDIASTORE)) {
                MS_proj.add(f);
            } else {
                MS_proj_thumbs.add(f);
            }
        }

        String[] MS_proj_thumbs_array = new String[MS_proj_thumbs.size()];
        MS_proj_thumbs_array = MS_proj_thumbs.toArray(MS_proj_thumbs_array);

        // add _ID column to Images.Media projection, for use in JOIN
        MS_proj.add("_ID");
        String[] MS_proj_array = new String[MS_proj.size()];
        MS_proj_array = MS_proj.toArray(MS_proj_array);

        Uri baseUri;

        // first, get cursor from MediaStore.Images.Thumbnails containing all thumbnails
        baseUri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI;
        Log.v("TEST", "Thumb: order by " + PhotoContract.ThumbEntry.COLUMN_DATE);
        Cursor c_thumbs = getContext().getContentResolver().query(baseUri, MS_proj_thumbs_array, null, null, PhotoContract.ThumbEntry.COLUMN_IMAGE_ID);
        if (c_thumbs == null || !c_thumbs.moveToFirst()) {
            Log.v("TEST", "MediaStore.Thumbnails cursor contains no data...");
            return null;
        }

        // then, get cursor from MediaStore.Images.Media (for TITLE and DESCRIPTION etc)
        // add _ID column to query
        baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        Cursor c_images = getContext().getContentResolver().query(baseUri, MS_proj_array, null, null, PhotoContract.ThumbEntry.COLUMN_IMAGE_PK);
        if (c_images == null || !c_images.moveToFirst()) {
            Log.v("TEST", "MediaStore.Images cursor contains no data...");
            return null;
        }

        // join these and return
        // the join is on images._ID = thumbnails.IMAGE_ID
        CursorJoiner joiner = new CursorJoiner(
                c_thumbs, new String[] { PhotoContract.ThumbEntry.COLUMN_IMAGE_ID },
                c_images, new String[] { PhotoContract.ThumbEntry.COLUMN_IMAGE_PK }
        );

        MatrixCursor retCursor = new MatrixCursor(projection);

        /*
        Does a join on two cursors using the specified columns.
        The cursors must already be sorted on each of the specified columns in ascending order.
        This joiner only supports the case where the tuple of key column values is unique.
        */
        for (CursorJoiner.Result joinerResult : joiner) {
            switch (joinerResult) {
                case LEFT:
                    // handle case where a row in cursorA is unique
                    break;
                case RIGHT:
                    // handle case where a row in cursorB is unique
                    break;
                case BOTH:

                    // handle case where a row with the same key is in both cursors
                    retCursor.addRow(new Object[]{
                            c_thumbs.getLong(0),  // ID
                            c_thumbs.getString(1), // data
                            c_thumbs.getLong(2), // image id
                            c_images.getString(0), // title
                            c_images.getString(1),  // desc
                            c_images.getLong(2)  // date
                    });
                    break;
            }
        }


        // https://stackoverflow.com/questions/12065606/getcontentresolver-query-cause-cursorwrapperinner-warning
        c_thumbs.close();
        c_images.close();

        return retCursor;

1 个答案:

答案 0 :(得分:0)

哈,似乎可以“欺骗”Android允许 CursorJoiner降序排序,只需按ID *( - 1)(升序)排序:

Cursor c_thumbs = getContext().getContentResolver().query(
                baseUri, 
                MS_proj_thumbs_array, null, null, 
                "(" + PhotoContract.ThumbEntry.COLUMN_IMAGE_ID + "*(-1))"  // NB!
       );

这样就解决了我的问题;最新的图像!

请在此处查看完整答案: Querying the MediaStore: Joining thumbnails and images (on ID)