From af598888b8a1f53336c8b57dcd701e211631f661 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 12 Jan 2021 16:49:53 +0800 Subject: [PATCH] add alternative media query syntax for Android 11 --- .../morbit/photogallery/PhotoGalleryPlugin.kt | 195 +++++++++++++++--- 1 file changed, 168 insertions(+), 27 deletions(-) diff --git a/android/src/main/kotlin/com/morbit/photogallery/PhotoGalleryPlugin.kt b/android/src/main/kotlin/com/morbit/photogallery/PhotoGalleryPlugin.kt index 07cf56e..9fd6f02 100644 --- a/android/src/main/kotlin/com/morbit/photogallery/PhotoGalleryPlugin.kt +++ b/android/src/main/kotlin/com/morbit/photogallery/PhotoGalleryPlugin.kt @@ -284,13 +284,48 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler { val limit = take ?: (total - offset) this.context?.run { - val imageCursor = this.contentResolver.query( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - imageMetadataProjection, - if (albumId == allAlbumId) null else "${MediaStore.Images.Media.BUCKET_ID} = $albumId", - null, - "$imageOrderBy LIMIT $limit OFFSET $offset" - ) + val imageCursor: Cursor? + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + imageCursor = this.contentResolver.query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + imageMetadataProjection, + android.os.Bundle().apply { + // Limit & Offset + putInt(android.content.ContentResolver.QUERY_ARG_LIMIT, limit) + putInt(android.content.ContentResolver.QUERY_ARG_OFFSET, offset) + // Sort + putStringArray( + android.content.ContentResolver.QUERY_ARG_SORT_COLUMNS, + arrayOf( + MediaStore.Images.Media.DATE_TAKEN, + MediaStore.Images.Media.DATE_MODIFIED + ) + ) + putIntArray( + android.content.ContentResolver.QUERY_ARG_SORT_DIRECTION, + intArrayOf( + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING, + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING + ) + ) + // Selection + if (albumId != allAlbumId) { + putString(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION, "${MediaStore.Images.Media.BUCKET_ID} = ?") + putStringArray(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(albumId)) + } + }, + null + ) + } else { + imageCursor = this.contentResolver.query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + imageMetadataProjection, + if (albumId == allAlbumId) null else "${MediaStore.Images.Media.BUCKET_ID} = $albumId", + null, + "$imageOrderBy LIMIT $limit OFFSET $offset" + ) + } imageCursor?.use { cursor -> while (cursor.moveToNext()) { @@ -312,12 +347,48 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler { val limit = take ?: (total - offset) this.context?.run { - val videoCursor = this.contentResolver.query( - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - videoMetadataProjection, - if (albumId == allAlbumId) null else "${MediaStore.Images.Media.BUCKET_ID} = $albumId", - null, - "$videoOrderBy LIMIT $limit OFFSET $offset") + val videoCursor: Cursor? + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + videoCursor = this.contentResolver.query( + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + videoMetadataProjection, + android.os.Bundle().apply { + // Limit & Offset + putInt(android.content.ContentResolver.QUERY_ARG_LIMIT, limit) + putInt(android.content.ContentResolver.QUERY_ARG_OFFSET, offset) + // Sort + putStringArray( + android.content.ContentResolver.QUERY_ARG_SORT_COLUMNS, + arrayOf( + MediaStore.Video.Media.DATE_TAKEN, + MediaStore.Video.Media.DATE_MODIFIED + ) + ) + putIntArray( + android.content.ContentResolver.QUERY_ARG_SORT_DIRECTION, + intArrayOf( + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING, + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING + ) + ) + // Selection + if (albumId != allAlbumId) { + putString(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION, "${MediaStore.Video.Media.BUCKET_ID} = ?") + putStringArray(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(albumId)) + } + }, + null + ) + } else { + videoCursor = this.contentResolver.query( + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + videoMetadataProjection, + if (albumId == allAlbumId) null else "${MediaStore.Video.Media.BUCKET_ID} = $albumId", + null, + "$videoOrderBy LIMIT $limit OFFSET $offset" + ) + } videoCursor?.use { cursor -> while (cursor.moveToNext()) { @@ -486,13 +557,48 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler { private fun getImageAlbumThumbnail(albumId: String, width: Int?, height: Int?): ByteArray? { return this.context?.run { - val imageCursor = this.contentResolver.query( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - arrayOf(MediaStore.Images.Media._ID), - if (albumId == allAlbumId) null else "${MediaStore.Images.Media.BUCKET_ID} = $albumId", - null, - MediaStore.Images.Media.DATE_TAKEN + " DESC LIMIT 1" - ) + val imageCursor: Cursor? + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + imageCursor = this.contentResolver.query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + arrayOf(MediaStore.Images.Media._ID), + android.os.Bundle().apply { + // Limit + putInt(android.content.ContentResolver.QUERY_ARG_LIMIT, 1) + // Sort + putStringArray( + android.content.ContentResolver.QUERY_ARG_SORT_COLUMNS, + arrayOf( + MediaStore.Images.Media.DATE_TAKEN, + MediaStore.Images.Media.DATE_MODIFIED + ) + ) + putIntArray( + android.content.ContentResolver.QUERY_ARG_SORT_DIRECTION, + intArrayOf( + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING, + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING + ) + ) + // Selection + if (albumId != allAlbumId) { + putString(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION, "${MediaStore.Images.Media.BUCKET_ID} = ?") + putStringArray(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(albumId)) + } + }, + null + ) + } else { + imageCursor = this.contentResolver.query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + arrayOf(MediaStore.Images.Media._ID), + if (albumId == allAlbumId) null else "${MediaStore.Images.Media.BUCKET_ID} = $albumId", + null, + MediaStore.Images.Media.DATE_TAKEN + " DESC LIMIT 1" + ) + } + imageCursor?.use { cursor -> if (cursor.moveToFirst()) { val idColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID) @@ -507,13 +613,48 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler { private fun getVideoAlbumThumbnail(albumId: String, width: Int?, height: Int?): ByteArray? { return this.context?.run { - val videoCursor = this.contentResolver.query( - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - arrayOf(MediaStore.Video.Media._ID), - if (albumId == allAlbumId) null else "${MediaStore.Video.Media.BUCKET_ID} = $albumId", - null, - MediaStore.Video.Media.DATE_TAKEN + " DESC LIMIT 1" - ) + val videoCursor: Cursor? + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + videoCursor = this.contentResolver.query( + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + arrayOf(MediaStore.Video.Media._ID), + android.os.Bundle().apply { + // Limit + putInt(android.content.ContentResolver.QUERY_ARG_LIMIT, 1) + // Sort + putStringArray( + android.content.ContentResolver.QUERY_ARG_SORT_COLUMNS, + arrayOf( + MediaStore.Video.Media.DATE_TAKEN, + MediaStore.Video.Media.DATE_MODIFIED + ) + ) + putIntArray( + android.content.ContentResolver.QUERY_ARG_SORT_DIRECTION, + intArrayOf( + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING, + android.content.ContentResolver.QUERY_SORT_DIRECTION_DESCENDING + ) + ) + // Selection + if (albumId != allAlbumId) { + putString(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION, "${MediaStore.Video.Media.BUCKET_ID} = ?") + putStringArray(android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(albumId)) + } + }, + null + ) + } else { + videoCursor = this.contentResolver.query( + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + arrayOf(MediaStore.Video.Media._ID), + if (albumId == allAlbumId) null else "${MediaStore.Video.Media.BUCKET_ID} = $albumId", + null, + MediaStore.Video.Media.DATE_TAKEN + " DESC LIMIT 1" + ) + } + videoCursor?.use { cursor -> if (cursor.moveToNext()) { val idColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID)