From 054cf60bcb5f238eea2c511f74b89ea794abc3c1 Mon Sep 17 00:00:00 2001 From: datdescartes Date: Thu, 11 Feb 2021 20:11:12 +0900 Subject: [PATCH] fixed the bug that Gallery picker option is not showing (#53) * fixed bug that Gallery picker option is not showing * fixing android Q permission * removed unused query permission * added workaround for android Q that only shows up 2 items * removing TODO, adding CHANGELOG for #20, #52 fixes * bugfixed, handle picker result on fragment Co-authored-by: dat --- CHANGELOG.md | 2 + cropper/src/main/AndroidManifest.xml | 10 +++ .../java/com/canhub/cropper/CropImage.java | 66 +++++++++++++------ .../com/canhub/cropper/CropImageOptions.kt | 2 +- .../app/CropImageViewFragment.kt | 30 +++++---- sample/src/main/res/layout/fragment_main.xml | 23 ++++--- 6 files changed, 86 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f149bf..27e01ace 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Fixed - Null CompressFormat [#44](https://github.com/CanHub/Android-Image-Cropper/issues/44) +- [Galley option not showing](https://github.com/CanHub/Android-Image-Cropper/issues/20) +- [Camera option not showing](https://github.com/CanHub/Android-Image-Cropper/issues/52) ## [2.0.3] - 27/01/21 Versions `2.0.1` and `2.0.2` are similar, issues with jitpack. diff --git a/cropper/src/main/AndroidManifest.xml b/cropper/src/main/AndroidManifest.xml index 95ca487b..eb27e699 100644 --- a/cropper/src/main/AndroidManifest.xml +++ b/cropper/src/main/AndroidManifest.xml @@ -1,6 +1,16 @@ + + + + + + + + + + @@ -153,7 +154,6 @@ public static Bitmap toOvalBitmap(@NonNull Bitmap bitmap) { * * @param activity the activity to be used to start activity from */ - // TODO Issue #20 public static void startPickImageActivity(@NonNull Activity activity) { activity.startActivityForResult( getPickImageChooserIntent(activity), PICK_IMAGE_CHOOSER_REQUEST_CODE); @@ -210,18 +210,10 @@ public static Intent getPickImageChooserIntent( allIntents.addAll(getCameraIntents(context, packageManager)); } - allIntents.add(getGalleryIntent(Intent.ACTION_GET_CONTENT, includeDocuments)); - - Intent target; - if (allIntents.isEmpty()) { - target = new Intent(); - } else { - target = allIntents.get(allIntents.size() - 1); - allIntents.remove(allIntents.size() - 1); - } + allIntents.addAll(getGalleryIntents(packageManager, Intent.ACTION_GET_CONTENT, includeDocuments)); // Create a chooser from the main intent - Intent chooserIntent = Intent.createChooser(target, title); + Intent chooserIntent = Intent.createChooser(allIntents.remove(allIntents.size()-1), title); // Add all other intents chooserIntent.putExtra( @@ -272,20 +264,54 @@ public static List getCameraIntents( allIntents.add(intent); } + // Just in case queryIntentActivities returns emptyList + if (allIntents.isEmpty()) { + allIntents.add(captureIntent); + } + return allIntents; } + /** * Get all Gallery intents for getting image from one of the apps of the device that handle * images. */ - public static Intent getGalleryIntent(String action, boolean includeDocuments) { - Intent galleryIntent = new Intent(); - galleryIntent.setAction(action); + public static List getGalleryIntents( + @NonNull PackageManager packageManager, String action, boolean includeDocuments) { + List intents = new ArrayList<>(); + Intent galleryIntent = new Intent(action); galleryIntent.setType(includeDocuments ? "*/*" : "image/*"); galleryIntent.addCategory(Intent.CATEGORY_OPENABLE); - return galleryIntent; + List listGallery = packageManager.queryIntentActivities(galleryIntent, 0); + if (CommonVersionCheck.INSTANCE.isAtLeastQ29() && listGallery.size() > 2) { + // Workaround for the bug that only 2 items are shown in Android Q + // // https://issuetracker.google.com/issues/134367295 + // Trying to pick best match items + Collections.sort(listGallery, (o1, o2) -> { + final String packageName = o1.activityInfo.packageName; + if (packageName.contains("photo")) return -1; + if (packageName.contains("gallery")) return -1; + if (packageName.contains("album")) return -1; + if (packageName.contains("media")) return -1; + return 0; + }); + listGallery = listGallery.subList(0, 2); + } + for (ResolveInfo res : listGallery) { + Intent intent = new Intent(galleryIntent); + intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); + intent.setPackage(res.activityInfo.packageName); + intents.add(intent); + } + + // Just in case queryIntentActivities returns emptyList + if (intents.isEmpty()) { + intents.add(galleryIntent); + } + + return intents; } /** diff --git a/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt b/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt index bc987b05..a9f4631e 100644 --- a/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt +++ b/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt @@ -433,7 +433,7 @@ open class CropImageOptions : Parcelable { } companion object { - + @JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator { override fun createFromParcel(parcel: Parcel): CropImageOptions? { diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/CropImageViewFragment.kt b/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/CropImageViewFragment.kt index 804ceea9..f9102d99 100644 --- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/CropImageViewFragment.kt +++ b/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/CropImageViewFragment.kt @@ -72,17 +72,16 @@ internal class CropImageViewFragment : OptionsDialogBottomSheet.show(childFragmentManager, options, this) } - // TODO Issue #20 -// binding.searchImage.setOnClickListener { -// context?.let { ctx -> -// if (CropImage.isExplicitCameraPermissionRequired(ctx)) { -// requestPermissions( -// arrayOf(Manifest.permission.CAMERA), -// CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE -// ) -// } else activity?.let { CropImage.startPickImageActivity(it) } -// } -// } + binding.searchImage.setOnClickListener { + context?.let { ctx -> + if (CropImage.isExplicitCameraPermissionRequired(ctx)) { + requestPermissions( + arrayOf(Manifest.permission.CAMERA), + CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE + ) + } else context?.let { context -> CropImage.startPickImageActivity(context, this) } + } + } binding.reset.setOnClickListener { binding.cropImageView.apply { @@ -157,9 +156,12 @@ internal class CropImageViewFragment : binding.cropImageView.setOnCropImageCompleteListener(null) } - override fun onSetImageUriComplete(view: CropImageView, uri: Uri, error: Exception) { - Log.e("AIC", "Failed to load image by URI", error) - Toast.makeText(activity, "Image load failed: " + error.message, Toast.LENGTH_LONG).show() + override fun onSetImageUriComplete(view: CropImageView, uri: Uri, error: Exception?) { + if (error != null) { + Log.e("AIC", "Failed to load image by URI", error) + Toast.makeText(activity, "Image load failed: " + error.message, Toast.LENGTH_LONG) + .show() + } } override fun onCropImageComplete(view: CropImageView, result: CropResult) { diff --git a/sample/src/main/res/layout/fragment_main.xml b/sample/src/main/res/layout/fragment_main.xml index 57129393..0b9516c3 100644 --- a/sample/src/main/res/layout/fragment_main.xml +++ b/sample/src/main/res/layout/fragment_main.xml @@ -45,17 +45,16 @@ app:pressedTranslationZ="@dimen/elevation_fab_pressed" tools:ignore="ContentDescription" /> - - - - - - - - - - - - +