From 33dfb99d35ea035a4858389dcb34027869674d24 Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Mon, 20 Jan 2020 19:52:42 +1100 Subject: [PATCH] fix(lib): Fix for pagination on Android. (#130) fixes #47 fixes #118 --- .../cameraroll/CameraRollModule.java | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/android/src/main/java/com/reactnativecommunity/cameraroll/CameraRollModule.java b/android/src/main/java/com/reactnativecommunity/cameraroll/CameraRollModule.java index 1e01f7a..5325133 100644 --- a/android/src/main/java/com/reactnativecommunity/cameraroll/CameraRollModule.java +++ b/android/src/main/java/com/reactnativecommunity/cameraroll/CameraRollModule.java @@ -280,10 +280,6 @@ public class CameraRollModule extends ReactContextBaseJavaModule { protected void doInBackgroundGuarded(Void... params) { StringBuilder selection = new StringBuilder("1"); List selectionArgs = new ArrayList<>(); - if (!TextUtils.isEmpty(mAfter)) { - selection.append(" AND " + SELECTION_DATE_TAKEN); - selectionArgs.add(mAfter); - } if (!TextUtils.isEmpty(mGroupName)) { selection.append(" AND " + SELECTION_BUCKET); selectionArgs.add(mGroupName); @@ -317,25 +313,30 @@ public class CameraRollModule extends ReactContextBaseJavaModule { } selection.replace(selection.length() - 1, selection.length(), ")"); } + WritableMap response = new WritableNativeMap(); ContentResolver resolver = mContext.getContentResolver(); - // using LIMIT in the sortOrder is not explicitly supported by the SDK (which does not support - // setting a limit at all), but it works because this specific ContentProvider is backed by - // an SQLite DB and forwards parameters to it without doing any parsing / validation. + try { + // set LIMIT to first + 1 so that we know how to populate page_info + String limit = "limit=" + (mFirst + 1); + + if (!TextUtils.isEmpty(mAfter)) { + limit = "limit=" + mAfter + "," + (mFirst + 1); + } + Cursor media = resolver.query( - MediaStore.Files.getContentUri("external"), + MediaStore.Files.getContentUri("external").buildUpon().encodedQuery(limit).build(), PROJECTION, selection.toString(), selectionArgs.toArray(new String[selectionArgs.size()]), - Images.Media.DATE_ADDED + " DESC, " + Images.Media.DATE_MODIFIED + " DESC LIMIT " + - (mFirst + 1)); // set LIMIT to first + 1 so that we know how to populate page_info + Images.Media.DATE_ADDED + " DESC, " + Images.Media.DATE_MODIFIED + " DESC"); if (media == null) { mPromise.reject(ERROR_UNABLE_TO_LOAD, "Could not get media"); } else { try { putEdges(resolver, media, response, mFirst); - putPageInfo(media, response, mFirst); + putPageInfo(media, response, mFirst, !TextUtils.isEmpty(mAfter) ? Integer.parseInt(mAfter) : 0); } finally { media.close(); mPromise.resolve(response); @@ -350,14 +351,14 @@ public class CameraRollModule extends ReactContextBaseJavaModule { } } - private static void putPageInfo(Cursor media, WritableMap response, int limit) { + private static void putPageInfo(Cursor media, WritableMap response, int limit, int offset) { WritableMap pageInfo = new WritableNativeMap(); pageInfo.putBoolean("has_next_page", limit < media.getCount()); if (limit < media.getCount()) { - media.moveToPosition(limit - 1); pageInfo.putString( - "end_cursor", - media.getString(media.getColumnIndex(Images.Media.DATE_TAKEN))); + "end_cursor", + Integer.toString(offset + limit) + ); } response.putMap("page_info", pageInfo); }