diff --git a/android/app/src/main/java/deckers/thibault/aves/channelhandlers/AppAdapterHandler.java b/android/app/src/main/java/deckers/thibault/aves/channelhandlers/AppAdapterHandler.java index b1ca601e5..79bb32486 100644 --- a/android/app/src/main/java/deckers/thibault/aves/channelhandlers/AppAdapterHandler.java +++ b/android/app/src/main/java/deckers/thibault/aves/channelhandlers/AppAdapterHandler.java @@ -6,6 +6,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; +import android.util.Log; import androidx.annotation.NonNull; @@ -13,12 +14,15 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import deckers.thibault.aves.utils.Utils; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; public class AppAdapterHandler implements MethodChannel.MethodCallHandler { public static final String CHANNEL = "deckers.thibault/aves/app"; + private static final String LOG_TAG = Utils.createLogTag(AppAdapterHandler.class); + private Context context; public AppAdapterHandler(Context context) { @@ -27,6 +31,7 @@ public class AppAdapterHandler implements MethodChannel.MethodCallHandler { @Override public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + Log.d(LOG_TAG, "onMethodCall method=" + call.method + ", arguments=" + call.arguments); switch (call.method) { case "getAppNames": { result.success(getAppNames()); diff --git a/android/app/src/main/java/deckers/thibault/aves/model/provider/MediaStoreImageProvider.java b/android/app/src/main/java/deckers/thibault/aves/model/provider/MediaStoreImageProvider.java index b9d21cd36..f2f8db71f 100644 --- a/android/app/src/main/java/deckers/thibault/aves/model/provider/MediaStoreImageProvider.java +++ b/android/app/src/main/java/deckers/thibault/aves/model/provider/MediaStoreImageProvider.java @@ -40,32 +40,37 @@ public class MediaStoreImageProvider extends ImageProvider { }).flatMap(Stream::of).toArray(String[]::new); public void fetchAll(Activity activity, EventChannel.EventSink entrySink) { - fetchFrom(activity, entrySink::success, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, null, null); - fetchFrom(activity, entrySink::success, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, VIDEO_PROJECTION, null, null); + NewEntryHandler success = entrySink::success; + fetchFrom(activity, success, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION); + fetchFrom(activity, success, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, VIDEO_PROJECTION); } @Override public void fetchSingle(final Activity activity, final Uri uri, final String mimeType, final ImageOpCallback callback) { long id = ContentUris.parseId(uri); - String selection = MediaStore.MediaColumns._ID + "=?"; - String[] selectionArgs = new String[]{String.valueOf(id)}; int entryCount = 0; + NewEntryHandler onSuccess = (entry) -> { + entry.put("uri", uri.toString()); + callback.onSuccess(entry); + }; if (mimeType.startsWith(Constants.MIME_IMAGE)) { - entryCount = fetchFrom(activity, callback::onSuccess, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, selection, selectionArgs); + Uri contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id); + entryCount = fetchFrom(activity, onSuccess, contentUri, IMAGE_PROJECTION); } else if (mimeType.startsWith(Constants.MIME_VIDEO)) { - entryCount = fetchFrom(activity, callback::onSuccess, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, VIDEO_PROJECTION, selection, selectionArgs); + Uri contentUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id); + entryCount = fetchFrom(activity, onSuccess, contentUri, VIDEO_PROJECTION); } if (entryCount == 0) { callback.onFailure(); } } - private int fetchFrom(final Activity activity, NewEntryHandler newEntryHandler, final Uri contentUri, String[] projection, String selection, String[] selectionArgs) { + private int fetchFrom(final Activity activity, NewEntryHandler newEntryHandler, final Uri contentUri, String[] projection) { String orderBy = MediaStore.MediaColumns.DATE_TAKEN + " DESC"; int entryCount = 0; try { - Cursor cursor = activity.getContentResolver().query(contentUri, projection, selection, selectionArgs, orderBy); + Cursor cursor = activity.getContentResolver().query(contentUri, projection, null, null, orderBy); if (cursor != null) { // image & video int idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID); @@ -84,6 +89,7 @@ public class MediaStoreImageProvider extends ImageProvider { while (cursor.moveToNext()) { long contentId = cursor.getLong(idColumn); + // this is fine if `contentUri` does not already contain the ID Uri itemUri = ContentUris.withAppendedId(contentUri, contentId); int width = cursor.getInt(widthColumn); // TODO TLAD sanitize mimeType diff --git a/lib/widgets/fullscreen/info/basic_section.dart b/lib/widgets/fullscreen/info/basic_section.dart index dd58d9976..40f007f4d 100644 --- a/lib/widgets/fullscreen/info/basic_section.dart +++ b/lib/widgets/fullscreen/info/basic_section.dart @@ -16,7 +16,8 @@ class BasicSection extends StatelessWidget { Widget build(BuildContext context) { final date = entry.bestDate; final dateText = date != null ? '${DateFormat.yMMMd().format(date)} at ${DateFormat.Hm().format(date)}' : '?'; - final resolutionText = '${entry.width ?? '?'} × ${entry.height ?? '?'}${(entry.isVideo || entry.isGif || entry.megaPixels == null) ? '' : ' (${entry.megaPixels} MP)'}'; + final showMegaPixels = !entry.isVideo && !entry.isGif && entry.megaPixels != null && entry.megaPixels > 0; + final resolutionText = '${entry.width ?? '?'} × ${entry.height ?? '?'}${showMegaPixels ? ' (${entry.megaPixels} MP)' : ''}'; return Column( crossAxisAlignment: CrossAxisAlignment.start,