Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a0f3b70
...
ashutosh2014 Mar 21, 2026
362cf17
Update ImagePickerUtils.java
ashutosh2014 Mar 21, 2026
afecdf1
........
ashutosh2014 Mar 22, 2026
f70492c
Merge remote-tracking branch 'upstream/main' into image-picker-Fix-an…
ashutosh2014 Mar 26, 2026
385d2e3
Update pubspec.yaml
ashutosh2014 Mar 26, 2026
da290e7
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Mar 26, 2026
b1a240d
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Mar 27, 2026
ce77b61
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Mar 29, 2026
748ba3b
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Mar 30, 2026
681bd67
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Apr 1, 2026
7194411
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Apr 1, 2026
76ed499
Merge remote-tracking branch 'upstream/main' into image-picker-Fix-an…
ashutosh2014 Apr 3, 2026
256b9f8
Merge branch 'image-picker-Fix-android-16-not-picking-up-file' of htt…
ashutosh2014 Apr 3, 2026
ab51db2
Merge remote-tracking branch 'upstream/main' into image-picker-Fix-an…
ashutosh2014 Apr 3, 2026
8eceb37
...
ashutosh2014 Apr 3, 2026
0d2e2bf
Merge branch 'main' into image-picker-Fix-android-16-not-picking-up-file
ashutosh2014 Apr 3, 2026
791842d
documents updated ....
ashutosh2014 Apr 8, 2026
e9c4b78
Merge remote-tracking branch 'upstream/main' into image-picker-Fix-an…
ashutosh2014 May 22, 2026
d758853
..
ashutosh2014 May 22, 2026
56d32af
..
ashutosh2014 May 22, 2026
190e593
Update README.md
ashutosh2014 May 22, 2026
0216750
Update README.md
ashutosh2014 May 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/image_picker/image_picker_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT

* Updates plugin to use Android Photo Picker on API 36 and above.
* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.

## 0.8.13+17
Expand Down
9 changes: 7 additions & 2 deletions packages/image_picker/image_picker_android/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ should add it to your `pubspec.yaml` as usual.

## Photo Picker

On Android 13 and above this packages uses the Android Photo Picker.
On Android 16 (API level 36) and above, gallery image, video, and mixed-media
picks always use the Android Photo Picker.
cannot be set to false to use the legacy ACTION_GET_CONTENT flow on those
versions. See [flutter/flutter#182071][5].

On Android 12 and below this package has optional Android Photo Picker functionality.
On Android 15 and below this package has optional Android Photo Picker functionality.

To use this feature, add the following code to your app before calling any `image_picker` APIs:

Expand All @@ -38,3 +41,5 @@ In addition, `ImagePickerAndroid.useAndroidPhotoPicker` must be set to `true` to
[1]: https://pub.dev/packages/image_picker
[2]: https://flutter.dev/to/endorsed-federated-plugin
[3]: https://developer.android.google.cn/reference/kotlin/androidx/activity/result/contract/ActivityResultContracts.PickMultipleVisualMedia
[4]: https://pub.dev/documentation/image_picker_android/latest/image_picker_android/ImagePickerAndroid/useAndroidPhotoPicker.htmlAdd a comment on line R52Add diff commentMarkdown input: edit mode selected.WritePreviewHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask listMentionReferenceMore Formatting tools items 0Saved repliesAdd FilesPaste, drop, or click to add filesCancelCommentStart a review
[5]: https://github.com/flutter/flutter/issues/182071
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public void chooseMediaFromGallery(

private void launchPickMediaFromGalleryIntent(GeneralOptions generalOptions) {
Intent pickMediaIntent;
if (generalOptions.getUsePhotoPicker()) {
if (ImagePickerUtils.effectiveUsePhotoPicker(generalOptions.getUsePhotoPicker())) {
if (generalOptions.getAllowMultiple()) {
int limit = ImagePickerUtils.getLimitFromOption(generalOptions);

Expand Down Expand Up @@ -353,7 +353,7 @@ public void chooseVideoFromGallery(

private void launchPickVideoFromGalleryIntent(Boolean usePhotoPicker) {
Intent pickVideoIntent;
if (usePhotoPicker) {
if (ImagePickerUtils.effectiveUsePhotoPicker(usePhotoPicker)) {
pickVideoIntent =
new ActivityResultContracts.PickVisualMedia()
.createIntent(
Expand Down Expand Up @@ -462,7 +462,7 @@ public void chooseMultiImageFromGallery(

private void launchPickImageFromGalleryIntent(Boolean usePhotoPicker) {
Intent pickImageIntent;
if (usePhotoPicker) {
if (ImagePickerUtils.effectiveUsePhotoPicker(usePhotoPicker)) {
pickImageIntent =
new ActivityResultContracts.PickVisualMedia()
.createIntent(
Expand All @@ -479,7 +479,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(
Expand Down Expand Up @@ -514,7 +514,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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import java.util.Arrays;

final class ImagePickerUtils {
private static final int API_LEVEL_36 = 36;
Comment thread
ashutosh2014 marked this conversation as resolved.

/** returns true, if permission present in manifest, otherwise false */
private static boolean isPermissionPresentInManifest(Context context, String permissionName) {
try {
Expand Down Expand Up @@ -86,4 +88,22 @@ static int getLimitFromOption(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}.
*
* <p>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
* would complete with no paths. The {@code PickVisualMedia} contract uses the Activity Result API
* and receives URIs reliably.
*
* <p>See <a href="https://github.com/flutter/flutter/issues/182071">flutter/flutter#182071</a>.
*/
static boolean effectiveUsePhotoPicker(boolean usePhotoPickerFromDart) {
return Build.VERSION.SDK_INT >= API_LEVEL_36 || usePhotoPickerFromDart;
}
Comment thread
ashutosh2014 marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ class ImagePickerAndroid extends ImagePickerPlatform {

final ImagePickerApi _hostApi;

/// Sets [ImagePickerAndroid] to use Android 13 Photo Picker.
/// Whether to use the Android Photo Picker on Android versions less than 16.
///
/// Currently defaults to false, but the default is subject to change.
/// On Android 16+ the Photo Picker is always used regardless of this setting.
///
/// On earlier Android versions, setting this to false uses the legacy
/// `ACTION_GET_CONTENT` picker instead of the Photo Picker.
///
/// Defaults to false.
bool useAndroidPhotoPicker = false;

/// Registers this class as the default platform implementation.
Expand Down