Skip to content

Commit

Permalink
fix(issues): fixes #1734 and #1874 by throwing and catching errors co…
Browse files Browse the repository at this point in the history
…rrectly (#1885)

* fix(issues): fixes #1734 and #1874 by throwing / catching errors correctly

* fix(removed): removed info log statements from code changes
  • Loading branch information
MattDennyir authored Dec 7, 2021
1 parent 9ed9e75 commit ed7d6f0
Showing 1 changed file with 80 additions and 19 deletions.
99 changes: 80 additions & 19 deletions android/src/main/java/com/imagepicker/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.util.Log;
import android.webkit.MimeTypeMap;

import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;
import androidx.exifinterface.media.ExifInterface;
Expand All @@ -37,12 +38,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;

Expand Down Expand Up @@ -350,18 +356,33 @@ public static boolean isCameraPermissionFulfilled(Context context, Activity acti
}

static boolean isImageType(Uri uri, Context context) {
final String imageMimeType = "image/";

return getMimeType(uri, context).contains(imageMimeType);
return Utils.isContentType("image/", uri, context);
}

static boolean isVideoType(Uri uri, Context context) {
final String videoMimeType = "video/";
return Utils.isContentType("video/", uri, context);
}

/**
* Verifies the content typs of a file URI. A helper function
* for isVideoType and isImageType
*
* @param contentMimeType - "video/" or "image/"
* @param uri - file uri
* @param context - react context
* @return a boolean to determine if file is of specified content type i.e. image or video
*/
static boolean isContentType(String contentMimeType, Uri uri, Context context) {
final String mimeType = getMimeType(uri, context);

if(mimeType != null) {
return mimeType.contains(contentMimeType);
}

return getMimeType(uri, context).contains(videoMimeType);
return false;
}

static String getMimeType(Uri uri, Context context) {
static @Nullable String getMimeType(Uri uri, Context context) {
if (uri.getScheme().equals("file")) {
return getMimeTypeFromFileUri(uri);
}
Expand Down Expand Up @@ -405,24 +426,64 @@ static ReadableMap getImageResponseMap(Uri uri, Options options, Context context
}

if(options.includeExtra) {
try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) {
ExifInterface exif = new ExifInterface(inputStream);
Date datetime = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse(exif.getAttribute(ExifInterface.TAG_DATETIME));
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String datetimeAsString = formatter.format(datetime);

// Add more exif data here ...

map.putString("timestamp", datetimeAsString);
} catch (Exception e) {
Log.e("RNIP", "Could not load image exif data: " + e.getMessage());
}
String datetime = getDateTimeExif(uri, context);
// Add more exif data here ...
map.putString("timestamp", datetime);
}

return map;
}

/**
* Gets the datetime exif data from a Uri
*
* @param uri - uri of file
* @param context - react context
* @return formatted timestamp
*/
static @Nullable String getDateTimeExif(Uri uri, Context context) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
ExifInterface exif = new ExifInterface(inputStream);
String datetimeTag = exif.getAttribute(ExifInterface.TAG_DATETIME);

if(datetimeTag != null) {
return getDateTimeInUTC(datetimeTag, "yyyy:MM:dd HH:mm:ss");
}

return null;
} catch (Exception e) {
// This error does not bubble up to RN as we don't want failed datetime retrieval to prevent selection
Log.e("RNIP", "Could not load image exif datetime: " + e.getMessage());
return null;
}
}

/**
* Converts a timestamp to a UTC timestamp
*
* @param value - timestamp
* @param format - input format
* @return formatted timestamp
*/
static @Nullable String getDateTimeInUTC(String value, String format) {
try {
Date datetime = new SimpleDateFormat(format, Locale.US).parse(value);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));

if (datetime != null) {
return formatter.format(datetime);
}

return null;
} catch (Exception e) {
// This error does not bubble up to RN as we don't want failed datetime parsing to prevent selection
Log.e("RNIP", "Could not parse image datetime to UTC: " + e.getMessage());
return null;
}
}

static ReadableMap getVideoResponseMap(Uri uri, Context context) {
String fileName = uri.getLastPathSegment();
WritableMap map = Arguments.createMap();
Expand Down

0 comments on commit ed7d6f0

Please sign in to comment.