From a0f3b705541181e40778c8de2ef1cd51610b4658 Mon Sep 17 00:00:00 2001 From: Ashutosh Agarwal Date: Sun, 22 Mar 2026 02:55:06 +0530 Subject: [PATCH 1/4] ... --- .../image_picker_android/CHANGELOG.md | 6 ++++ .../imagepicker/ImagePickerDelegate.java | 10 +++--- .../plugins/imagepicker/ImagePickerUtils.java | 21 +++++++++++++ .../imagepicker/ImagePickerUtilsTest.java | 31 +++++++++++++++++++ .../image_picker_android/pubspec.yaml | 2 +- 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerUtilsTest.java diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md index 7f2e33347447..052a8769d960 100644 --- a/packages/image_picker/image_picker_android/CHANGELOG.md +++ b/packages/image_picker/image_picker_android/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.8.13+15 + +* Fixes gallery image/video selection on Android 16 (API 36) returning no paths when + `useAndroidPhotoPicker` was false. The plugin now uses the Android Photo Picker on API 36 and + above regardless of that flag, avoiding a broken `ACTION_GET_CONTENT` result from the system UI. + ## 0.8.13+14 * Bumps androidx.activity:activity from 1.12.2 to 1.12.4. diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java index 043546de2b3e..b5ff2e53fbb1 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java @@ -296,7 +296,7 @@ public void chooseMediaFromGallery( private void launchPickMediaFromGalleryIntent(Messages.GeneralOptions generalOptions) { Intent pickMediaIntent; - if (generalOptions.getUsePhotoPicker()) { + if (ImagePickerUtils.effectiveUsePhotoPicker(generalOptions.getUsePhotoPicker())) { if (generalOptions.getAllowMultiple()) { int limit = ImagePickerUtils.getLimitFromOption(generalOptions); @@ -342,7 +342,7 @@ public void chooseVideoFromGallery( private void launchPickVideoFromGalleryIntent(Boolean usePhotoPicker) { Intent pickVideoIntent; - if (usePhotoPicker) { + if (ImagePickerUtils.effectiveUsePhotoPicker(usePhotoPicker)) { pickVideoIntent = new ActivityResultContracts.PickVisualMedia() .createIntent( @@ -441,7 +441,7 @@ public void chooseMultiImageFromGallery( private void launchPickImageFromGalleryIntent(Boolean usePhotoPicker) { Intent pickImageIntent; - if (usePhotoPicker) { + if (ImagePickerUtils.effectiveUsePhotoPicker(usePhotoPicker)) { pickImageIntent = new ActivityResultContracts.PickVisualMedia() .createIntent( @@ -458,7 +458,7 @@ private void launchPickImageFromGalleryIntent(Boolean usePhotoPicker) { private void launchMultiPickImageFromGalleryIntent(Boolean usePhotoPicker, int limit) { Intent pickMultiImageIntent; - if (usePhotoPicker) { + if (ImagePickerUtils.effectiveUsePhotoPicker(usePhotoPicker)) { pickMultiImageIntent = new ActivityResultContracts.PickMultipleVisualMedia(limit) .createIntent( @@ -490,7 +490,7 @@ public void chooseMultiVideoFromGallery( private void launchMultiPickVideoFromGalleryIntent(Boolean usePhotoPicker, int limit) { Intent pickMultiVideoIntent; - if (usePhotoPicker) { + if (ImagePickerUtils.effectiveUsePhotoPicker(usePhotoPicker)) { pickMultiVideoIntent = new ActivityResultContracts.PickMultipleVisualMedia(limit) .createIntent( diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java index 1499a860d7d2..a9d451f41e2b 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java @@ -86,4 +86,25 @@ static int getLimitFromOption(Messages.GeneralOptions generalOptions) { return effectiveLimit; } + + /** + * Returns whether gallery/media selection should use {@link + * androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia} (Android Photo + * Picker) instead of {@link android.content.Intent#ACTION_GET_CONTENT}. + * + *

On Android 16 (API 36), {@code ACTION_GET_CONTENT} for images may be handled by the system + * photo picker's {@code PhotopickerGetContentActivity}. That path combined with {@code + * startActivityForResult} can return {@link android.app.Activity#RESULT_OK} without {@link + * android.content.Intent#getData()} or usable {@link android.content.ClipData}, so the plugin + * would complete with no paths. The {@code PickVisualMedia} contract uses the Activity Result API + * and receives URIs reliably. + * + *

See flutter/flutter#182071. + */ + static boolean effectiveUsePhotoPicker(boolean usePhotoPickerFromDart) { + if (Build.VERSION.SDK_INT >= 36) { + return true; + } + return usePhotoPickerFromDart; + } } diff --git a/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerUtilsTest.java b/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerUtilsTest.java new file mode 100644 index 000000000000..396c84410545 --- /dev/null +++ b/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerUtilsTest.java @@ -0,0 +1,31 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.imagepicker; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +public class ImagePickerUtilsTest { + + @Test + @Config(sdk = 35) + public void effectiveUsePhotoPicker_belowApi36_usesDartPreference() { + assertFalse(ImagePickerUtils.effectiveUsePhotoPicker(false)); + assertTrue(ImagePickerUtils.effectiveUsePhotoPicker(true)); + } + + @Test + @Config(sdk = 36) + public void effectiveUsePhotoPicker_onApi36_alwaysUsesPhotoPicker() { + assertTrue(ImagePickerUtils.effectiveUsePhotoPicker(false)); + assertTrue(ImagePickerUtils.effectiveUsePhotoPicker(true)); + } +} diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index 37dfcbaf8654..aba9ecbef800 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_android description: Android implementation of the image_picker plugin. repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.13+14 +version: 0.8.13+15 environment: sdk: ^3.9.0 From 362cf1764e0fc10dbc392d715f7a3f8a2bca7555 Mon Sep 17 00:00:00 2001 From: Ashutosh Agarwal Date: Sun, 22 Mar 2026 03:07:48 +0530 Subject: [PATCH 2/4] Update ImagePickerUtils.java --- .../io/flutter/plugins/imagepicker/ImagePickerUtils.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java index a9d451f41e2b..73ce50bfa8df 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java @@ -15,6 +15,8 @@ import java.util.Arrays; final class ImagePickerUtils { + private static final int ANDROID_16_API_LEVEL = 36; + /** returns true, if permission present in manifest, otherwise false */ private static boolean isPermissionPresentInManifest(Context context, String permissionName) { try { @@ -102,9 +104,6 @@ static int getLimitFromOption(Messages.GeneralOptions generalOptions) { *

See flutter/flutter#182071. */ static boolean effectiveUsePhotoPicker(boolean usePhotoPickerFromDart) { - if (Build.VERSION.SDK_INT >= 36) { - return true; - } - return usePhotoPickerFromDart; + return Build.VERSION.SDK_INT >= ANDROID_16_API_LEVEL || usePhotoPickerFromDart; } } From afecdf1c0178a05f9fe3113356b41d9270f5c875 Mon Sep 17 00:00:00 2001 From: Ashutosh Agarwal Date: Sun, 22 Mar 2026 23:18:11 +0530 Subject: [PATCH 3/4] ........ --- packages/image_picker/image_picker_android/CHANGELOG.md | 2 +- .../io/flutter/plugins/imagepicker/ImagePickerUtils.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md index 052a8769d960..eface698e3e1 100644 --- a/packages/image_picker/image_picker_android/CHANGELOG.md +++ b/packages/image_picker/image_picker_android/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.8.13+15 -* Fixes gallery image/video selection on Android 16 (API 36) returning no paths when +* Fixes gallery image/video selection on Android API 36+ returning no paths when `useAndroidPhotoPicker` was false. The plugin now uses the Android Photo Picker on API 36 and above regardless of that flag, avoiding a broken `ACTION_GET_CONTENT` result from the system UI. diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java index 73ce50bfa8df..97b221ca810f 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerUtils.java @@ -15,7 +15,7 @@ import java.util.Arrays; final class ImagePickerUtils { - private static final int ANDROID_16_API_LEVEL = 36; + private static final int API_LEVEL_36 = 36; /** returns true, if permission present in manifest, otherwise false */ private static boolean isPermissionPresentInManifest(Context context, String permissionName) { @@ -94,7 +94,7 @@ static int getLimitFromOption(Messages.GeneralOptions generalOptions) { * androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia} (Android Photo * Picker) instead of {@link android.content.Intent#ACTION_GET_CONTENT}. * - *

On Android 16 (API 36), {@code ACTION_GET_CONTENT} for images may be handled by the system + *

On Android API 36+, {@code ACTION_GET_CONTENT} for images may be handled by the system * photo picker's {@code PhotopickerGetContentActivity}. That path combined with {@code * startActivityForResult} can return {@link android.app.Activity#RESULT_OK} without {@link * android.content.Intent#getData()} or usable {@link android.content.ClipData}, so the plugin @@ -104,6 +104,6 @@ static int getLimitFromOption(Messages.GeneralOptions generalOptions) { *

See flutter/flutter#182071. */ static boolean effectiveUsePhotoPicker(boolean usePhotoPickerFromDart) { - return Build.VERSION.SDK_INT >= ANDROID_16_API_LEVEL || usePhotoPickerFromDart; + return Build.VERSION.SDK_INT >= API_LEVEL_36 || usePhotoPickerFromDart; } } From 385d2e3465705beed29442abb64f28edc66537c4 Mon Sep 17 00:00:00 2001 From: Ashutosh Agarwal Date: Thu, 26 Mar 2026 14:00:38 +0530 Subject: [PATCH 4/4] Update pubspec.yaml --- packages/image_picker/image_picker_android/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index aba9ecbef800..a2ed7681559b 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_android description: Android implementation of the image_picker plugin. repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.13+15 +version: 0.8.13+16 environment: sdk: ^3.9.0