在Android Q上查询MediaStore

3

我正在使用MediaStore获取所有图片的相册,之前在Android Q之前都能正常工作。但今天我将编译版本提升到29,它抛出了以下异常:

android.database.sqlite.SQLiteException: near "GROUP": syntax error (code 1 SQLITE_ERROR): , while compiling: SELECT bucket_id, bucket_display_name, mime_type FROM images WHERE ((is_pending=0) AND (is_trashed=0) AND (volume_name IN ( 'external_primary' ))) AND ( GROUP BY bucket_id )

以下是我查询MediaStore的代码:

    String[] PROJECTION_BUCKET = {
            MediaStore.Images.ImageColumns.BUCKET_ID,
            MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
            MediaStore.Images.ImageColumns.MIME_TYPE};

    String BUCKET_GROUP_BY = "1) GROUP BY 1,(2";
    String BUCKET_ORDER_BY = "MAX(datetaken) DESC";

    Cursor cur = context.getContentResolver().query(getUriOfType(type),
            PROJECTION_BUCKET,
            BUCKET_GROUP_BY,
            null,
            BUCKET_ORDER_BY);

Android Q 中不支持 As Group, 有什么解决办法吗?


2
摆脱那个SQL,因为它对数据库结构做出了一些假设,在所有版本的SQL上都不会有效。对于你的三列数据进行简单的投影。在Java中进行最大值计算、分组和排序。 - CommonsWare
3
如果我们仍需要通过Java实现这个操作,那么使用SQL就没有意义了。 - Mateen Chaudhry
10
任何ContentProvider的实现不要求使用符合SQL标准的数据库。特别地,没有要求MediaStore必须使用符合SQL标准的数据库。你使用了一种技巧,在某些设备上一段时间内运行良好。现在你抱怨这种技巧不起作用了。最初就不应该使用这种技巧,因为从来没有保证任意的SQL都可以被破解成MediaStore查询。所以,请利用这个机会修复你的代码,并使其在不同设备和版本上更加可靠。 - CommonsWare
2
@EpicPandaForce:唉,希望一些现任或前任的谷歌工程师读了我的博客文章会感到尴尬。 - CommonsWare
1
"您能否用代码回答并解释一下这个问题?" -- 我对您的代码尝试实现的目标不够了解,无法快速提供Java等效代码。 - CommonsWare
显示剩余7条评论
1个回答

0
GROUP BY 在 Android 10(Q) 上已经不再起作用,COUNT 也是如此。 下面的代码片段可能会对你有帮助。
String path = null;
String album = null;
String timestamp = null;
String countPhoto = null;
Uri uriExternal = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri uriInternal = android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI;
String[] projection = {
        MediaStore.MediaColumns.DATA,
        MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
        MediaStore.MediaColumns.DATE_MODIFIED
};
Cursor cursorExternal = getContentResolver().query(uriExternal, projection, "_data IS NOT NULL", null, null);
Cursor cursorInternal = getContentResolver().query(uriInternal, projection, "_data IS NOT NULL", null, null);
Cursor cursor = new MergeCursor(new Cursor[]{cursorExternal, cursorInternal});
while(cursor.moveToNext()){
    path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA));
    album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
    timestamp = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED));
    countPhoto = Function.getCount(getApplicationContext(), album);
    albumOrPhotoList.add(Function.mappingInbox(album, path, timestamp, Function.converToTime(timestamp), countPhoto));
}
cursor.close();
Collections.sort(albumOrPhotoList,new
// Arranging photo album by timestamp decending
MapComparator(Function.KEY_TIMESTAMP, "dsc")); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接