Skip to content

Commit

Permalink
Implement the new official Android Photo Picker (#2093)
Browse files Browse the repository at this point in the history
* Test implementation for new Android Photo Picker SDK

* Add fix for when a single image is returned as clipData

---------

Co-authored-by: Pauli Kettunen <[email protected]>
  • Loading branch information
Pauligrinder and Pauli Kettunen authored Jan 16, 2025
1 parent 174f609 commit e9e572b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 19 deletions.
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"
}
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 @@ -25,6 +25,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 @@ -41,8 +43,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 @@ -365,28 +367,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 @@ -801,7 +807,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

0 comments on commit e9e572b

Please sign in to comment.