Skip to content

Implement the new official Android Photo Picker #2093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ android {
abortOnError false
}
}

dependencies {
implementation 'com.facebook.react:react-native:+'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'com.github.yalantis:ucrop:2.2.6-native'
implementation 'androidx.activity:activity:1.9.2'
implementation "androidx.core:core:1.13.1"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changed forces compileSdkVersion to be set at 34 it seems, can be a breaking change.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1Jesper1 I don't know what kind of apps are you developing but settings the compileSdkVersion and targetSdkVersion to 34 is a requirement now. You can't set it lower than 34.
https://support.google.com/googleplay/android-developer/answer/11926878?hl=en&sjid=13755100570201605452-EU

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See "Existing apps must target Android 13 (API level 33) or higher"
@rpopovici Our existing app has compileSdkVersion 33, changing to 34 breaks building our app. I need to do additional changes. (upgrading other packages and using newer Gradle).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Pauligrinder Were these the lowest version to use? Or can we use lower versions to targetSdkVersion 33?
If not we might want to create a PR to update the build.gradle and the README.
https://github.com/Pauligrinder/react-native-image-crop-picker/blob/0f8db423b8d317897c6266c8194fc630f2e43612/android/build.gradle#L3 to 34.

compileSdkVersion = 33
to 34.
And set a warning for a possible breaking change in https://github.com/ivpusic/react-native-image-crop-picker/releases/tag/v0.42.0

Copy link
Contributor Author

@Pauligrinder Pauligrinder Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, unfortunately. I think I wrote in the initial description that someone who knows these better might wanna check the dependencies and set them as low as possible.

I just set them to values that worked for me.

My tip for you @1Jesper1 is, if you really need SDK33 support quickly, is to do the work yourself - fork the library, clone your fork to your machine, lower the versions as much as you need and push the changes to your fork. Then install your own fork into your app and see if it works. If it doesn't, then keep changing the versions until you find a combination that works.

Then you can make a PR of it and maybe someone else will also benefit from your work.

That's how open source is supposed to work 😉

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Pauligrinder No problem and thnx for the new picker, I have migrated to 34, but it might be helpful for users which are on 33 currently. If I have some time will check if lower versions are possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, might not be worth the effort since SDK34 is basically already required to submit a new app or update to the Play Store (SDK33 is OK for existing apps only).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
3 changes: 1 addition & 2 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Tue May 17 14:28:43 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
10 changes: 10 additions & 0 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />


<!-- Prompt Google Play services to install the backported photo picker module -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies" android:enabled="false" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
</intent-filter>

<meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import android.Manifest;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
Expand All @@ -18,6 +18,8 @@
import android.util.Base64;
import android.util.Log;
import android.webkit.MimeTypeMap;
import androidx.activity.result.PickVisualMediaRequest;
import androidx.activity.result.contract.ActivityResultContracts;

import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;
Expand All @@ -40,8 +42,8 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand Down Expand Up @@ -364,28 +366,32 @@ private void initiateCamera(Activity activity) {

private void initiatePicker(final Activity activity) {
try {
final Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
PickVisualMediaRequest.Builder builder = new PickVisualMediaRequest.Builder();
PickVisualMediaRequest request = new PickVisualMediaRequest();

if (cropping || mediaType.equals("photo")) {
galleryIntent.setType("image/*");
request = builder.setMediaType(new ActivityResultContracts.PickVisualMedia.SingleMimeType("image/*")).build();
}
else{
if (cropping) {
String[] mimetypes = {"image/jpeg", "image/png"};
galleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
request = builder.setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE).build();
}
} else if (mediaType.equals("video")) {
galleryIntent.setType("video/*");
else if (mediaType.equals("video")) {
request = builder.setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly.INSTANCE).build();
} else {
galleryIntent.setType("*/*");
String[] mimetypes = {"image/*", "video/*"};
galleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
request = builder.setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.INSTANCE).build();
}
}

galleryIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
galleryIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple);
galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);
Intent intent;

final Intent chooserIntent = Intent.createChooser(galleryIntent, "Pick an image");
activity.startActivityForResult(chooserIntent, IMAGE_PICKER_REQUEST);
if (multiple) {
intent = new ActivityResultContracts.PickMultipleVisualMedia().createIntent(activity, request);
} else {
intent = new ActivityResultContracts.PickVisualMedia().createIntent(activity, request);
}

activity.startActivityForResult(intent, IMAGE_PICKER_REQUEST);
} catch (Exception e) {
resultCollector.notifyProblem(E_FAILED_TO_SHOW_PICKER, e);
}
Expand Down Expand Up @@ -790,7 +796,17 @@ private void imagePickerResult(Activity activity, final int requestCode, final i
} else {
Uri uri = data.getData();

// if the result comes in clipData format (which apparently it does in some cases)
if (uri == null) {
ClipData clipData = data.getClipData();
if (clipData != null && clipData.getItemCount() > 0) {
ClipData.Item item = clipData.getItemAt(0);
uri = item.getUri();
}
}

// error out if uri is still null
if(uri == null) {
resultCollector.notifyProblem(E_NO_IMAGE_DATA_FOUND, "Cannot resolve image url");
return;
}
Expand Down