Skip to content
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

[android] return the 'originFilepath' when select image #2077

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,23 @@ The `callback` will be called with a response object, refer to [The Response Obj

## Asset Object

| key | iOS | Android | Web | Photo/Video | Requires Permissions | Description |
| --------- | --- | ------- | --- | ----------- | -------------------- | ------------------------- |
| base64 | OK | OK | OK | PHOTO ONLY | NO | The base64 string of the image (photos only) |
| uri | OK | OK | OK | BOTH | NO | The file uri in app specific cache storage. Except when picking **video from Android gallery** where you will get read only content uri, to get file uri in this case copy the file to app specific storage using any react-native library. For web it uses the base64 as uri. |
| width | OK | OK | OK | BOTH | NO | Asset dimensions |
| height | OK | OK | OK | BOTH | NO | Asset dimensions |
| fileSize | OK | OK | NO | BOTH | NO | The file size |
| type | OK | OK | NO | BOTH | NO | The file type |
| fileName | OK | OK | NO | BOTH | NO | The file name |
| duration | OK | OK | NO | VIDEO ONLY | NO | The selected video duration in seconds |
| bitrate | --- | OK | NO | VIDEO ONLY | NO | The average bitrate (in bits/sec) of the selected video, if available. (Android only) |
| timestamp | OK | OK | NO | BOTH | YES | Timestamp of the asset. Only included if 'includeExtra' is true |
| id | OK | OK | NO | BOTH | YES | local identifier of the photo or video. On Android, this is the same as fileName |
| key | iOS | Android | Web | Photo/Video | Requires Permissions | Description |
|----------------|--------|---------|-----|-------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| base64 | OK | OK | OK | PHOTO ONLY | NO | The base64 string of the image (photos only) |
| uri | OK | OK | OK | BOTH | NO | The file uri in app specific cache storage. Except when picking **video from Android gallery** where you will get read only content uri, to get file uri in this case copy the file to app specific storage using any react-native library. For web it uses the base64 as uri. |
| width | OK | OK | OK | BOTH | NO | Asset dimensions |
| height | OK | OK | OK | BOTH | NO | Asset dimensions |
| fileSize | OK | OK | NO | BOTH | NO | The file size |
| type | OK | OK | NO | BOTH | NO | The file type |
| fileName | OK | OK | NO | BOTH | NO | The file name |
| duration | OK | OK | NO | VIDEO ONLY | NO | The selected video duration in seconds |
| bitrate | --- | OK | NO | VIDEO ONLY | NO | The average bitrate (in bits/sec) of the selected video, if available. (Android only) |
| timestamp | OK | OK | NO | BOTH | YES | Timestamp of the asset. Only included if 'includeExtra' is true |
| id | OK | OK | NO | BOTH | YES | local identifier of the photo or video. On Android, this is the same as fileName |
| originFilepath | **NO** | OK | NO | PHOTO ONLY | YES | thr origin file path **when select image** |

**waring:** the `uri` is point at a temporary file! When you pick a same image twice, it will be two different `uri`,
the `fileName` also to be the temporary file's name.

## Note on file storage

Expand Down
37 changes: 36 additions & 1 deletion android/src/main/java/com/imagepicker/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.camera2.CameraCharacteristics;
Expand Down Expand Up @@ -418,6 +419,14 @@ static ReadableMap getImageResponseMap(Uri uri, Options options, Context context
return map;
}

static ReadableMap getImageResponseMap(Uri tempFileUri, String originFilePath, Options options, Context context) {
WritableMap imageResponseMap = (WritableMap) getImageResponseMap(tempFileUri, options, context);
if (originFilePath != null) {
imageResponseMap.putString("originFilepath", originFilePath);
}
return imageResponseMap;
}

static ReadableMap getVideoResponseMap(Uri uri, Options options, Context context) {
String fileName = uri.getLastPathSegment();
WritableMap map = Arguments.createMap();
Expand Down Expand Up @@ -449,11 +458,15 @@ static ReadableMap getResponseMap(List<Uri> fileUris, Options options, Context c

// Call getAppSpecificStorageUri in the if block to avoid copying unsupported files
if (isImageType(uri, context)) {
String originPath;
if (uri.getScheme().contains("content")) {
originPath = getImageFilepathFromContentProtocol(uri, context);
uri = getAppSpecificStorageUri(uri, context);
} else {
originPath = uri.toString();
}
uri = resizeImage(uri, context, options);
assets.pushMap(getImageResponseMap(uri, options, context));
assets.pushMap(getImageResponseMap(uri, originPath, options, context));
} else if (isVideoType(uri, context)) {
if (uri.getScheme().contains("content")) {
uri = getAppSpecificStorageUri(uri, context);
Expand All @@ -470,6 +483,28 @@ static ReadableMap getResponseMap(List<Uri> fileUris, Options options, Context c
return response;
}

/**
* get the image filepath from the 'content' protocol.
* @param uri the uri.
* @param context the context.
* @return the filepath. return null when the file is not exist.
* <p>
* the return value may like this:
* <p>
* <code>/storage/emulated/0/Pictures/-4fae8f0985703cbe.jpg</code>
*/
private static String getImageFilepathFromContentProtocol(Uri uri, Context context) {
String[] proj = { MediaStore.Images.Media.DATA };
try (Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null)) {
int index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
if (index == -1) {
return null;
}
cursor.moveToFirst();
return cursor.getString(index);
}
}

static ReadableMap getErrorMap(String errCode, String errMsg) {
WritableMap map = Arguments.createMap();
map.putString("errorCode", errCode);
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export interface Asset {
bitrate?: number;
timestamp?: string;
id?: string;
/**
* the origin filepath <b>when select image</b>.(android only)
*/
originFilepath?: string
}

export interface ImagePickerResponse {
Expand Down