698 lines
22 KiB
Java
698 lines
22 KiB
Java
package com.imagepicker;
|
|
|
|
import android.app.Activity;
|
|
import android.app.AlertDialog;
|
|
import android.content.ActivityNotFoundException;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.database.Cursor;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BitmapFactory;
|
|
import android.graphics.Matrix;
|
|
import android.media.ExifInterface;
|
|
import android.net.Uri;
|
|
import android.os.Environment;
|
|
import android.provider.MediaStore;
|
|
import android.util.Base64;
|
|
import android.widget.ArrayAdapter;
|
|
import android.webkit.MimeTypeMap;
|
|
import android.content.pm.PackageManager;
|
|
|
|
import com.facebook.react.bridge.ActivityEventListener;
|
|
import com.facebook.react.bridge.Arguments;
|
|
import com.facebook.react.bridge.Callback;
|
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
import com.facebook.react.bridge.ReactMethod;
|
|
import com.facebook.react.bridge.ReadableMap;
|
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
import com.facebook.react.bridge.WritableMap;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
public class ImagePickerModule extends ReactContextBaseJavaModule implements ActivityEventListener {
|
|
|
|
static final int REQUEST_LAUNCH_IMAGE_CAPTURE = 1;
|
|
static final int REQUEST_LAUNCH_IMAGE_LIBRARY = 2;
|
|
static final int REQUEST_LAUNCH_VIDEO_LIBRARY = 3;
|
|
static final int REQUEST_LAUNCH_VIDEO_CAPTURE = 4;
|
|
|
|
private final ReactApplicationContext mReactContext;
|
|
|
|
private Uri mCameraCaptureURI;
|
|
private Uri mCropImagedUri;
|
|
private Callback mCallback;
|
|
private Boolean noData = false;
|
|
private Boolean tmpImage;
|
|
private Boolean allowEditing = false;
|
|
private Boolean pickVideo = false;
|
|
private int maxWidth = 0;
|
|
private int maxHeight = 0;
|
|
private int aspectX = 0;
|
|
private int aspectY = 0;
|
|
private int quality = 100;
|
|
private int angle = 0;
|
|
private Boolean forceAngle = false;
|
|
private int videoQuality = 1;
|
|
private int videoDurationLimit = 0;
|
|
WritableMap response;
|
|
|
|
public ImagePickerModule(ReactApplicationContext reactContext) {
|
|
super(reactContext);
|
|
|
|
reactContext.addActivityEventListener(this);
|
|
|
|
mReactContext = reactContext;
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "ImagePickerManager";
|
|
}
|
|
|
|
@ReactMethod
|
|
public void showImagePicker(final ReadableMap options, final Callback callback) {
|
|
Activity currentActivity = getCurrentActivity();
|
|
|
|
if (currentActivity == null) {
|
|
response = Arguments.createMap();
|
|
response.putString("error", "can't find current Activity");
|
|
callback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
final List<String> titles = new ArrayList<String>();
|
|
final List<String> actions = new ArrayList<String>();
|
|
|
|
String cancelButtonTitle = getReactApplicationContext().getString(android.R.string.cancel);
|
|
|
|
if (options.hasKey("takePhotoButtonTitle")
|
|
&& options.getString("takePhotoButtonTitle") != null
|
|
&& !options.getString("takePhotoButtonTitle").isEmpty()
|
|
&& isCameraAvailable()) {
|
|
titles.add(options.getString("takePhotoButtonTitle"));
|
|
actions.add("photo");
|
|
}
|
|
if (options.hasKey("chooseFromLibraryButtonTitle")
|
|
&& options.getString("chooseFromLibraryButtonTitle") != null
|
|
&& !options.getString("chooseFromLibraryButtonTitle").isEmpty()) {
|
|
titles.add(options.getString("chooseFromLibraryButtonTitle"));
|
|
actions.add("library");
|
|
}
|
|
if (options.hasKey("cancelButtonTitle")
|
|
&& !options.getString("cancelButtonTitle").isEmpty()) {
|
|
cancelButtonTitle = options.getString("cancelButtonTitle");
|
|
}
|
|
|
|
if (options.hasKey("customButtons")) {
|
|
ReadableMap buttons = options.getMap("customButtons");
|
|
ReadableMapKeySetIterator it = buttons.keySetIterator();
|
|
// Keep the current size as the iterator returns the keys in the reverse order they are defined
|
|
int currentIndex = titles.size();
|
|
while (it.hasNextKey()) {
|
|
String key = it.nextKey();
|
|
|
|
titles.add(currentIndex, key);
|
|
actions.add(currentIndex, buttons.getString(key));
|
|
}
|
|
}
|
|
|
|
titles.add(cancelButtonTitle);
|
|
actions.add("cancel");
|
|
|
|
ArrayAdapter<String> adapter = new ArrayAdapter<String>(currentActivity,
|
|
android.R.layout.select_dialog_item, titles);
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(currentActivity);
|
|
if (options.hasKey("title") && options.getString("title") != null && !options.getString("title").isEmpty()) {
|
|
builder.setTitle(options.getString("title"));
|
|
}
|
|
|
|
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
|
|
public void onClick(DialogInterface dialog, int index) {
|
|
String action = actions.get(index);
|
|
response = Arguments.createMap();
|
|
|
|
switch (action) {
|
|
case "photo":
|
|
launchCamera(options, callback);
|
|
break;
|
|
case "library":
|
|
launchImageLibrary(options, callback);
|
|
break;
|
|
case "cancel":
|
|
response.putBoolean("didCancel", true);
|
|
callback.invoke(response);
|
|
break;
|
|
default: // custom button
|
|
response.putString("customButton", action);
|
|
callback.invoke(response);
|
|
}
|
|
}
|
|
});
|
|
|
|
final AlertDialog dialog = builder.create();
|
|
/**
|
|
* override onCancel method to callback cancel in case of a touch outside of
|
|
* the dialog or the BACK key pressed
|
|
*/
|
|
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
|
@Override
|
|
public void onCancel(DialogInterface dialog) {
|
|
response = Arguments.createMap();
|
|
dialog.dismiss();
|
|
response.putBoolean("didCancel", true);
|
|
callback.invoke(response);
|
|
}
|
|
});
|
|
dialog.show();
|
|
}
|
|
|
|
// NOTE: Currently not reentrant / doesn't support concurrent requests
|
|
@ReactMethod
|
|
public void launchCamera(final ReadableMap options, final Callback callback) {
|
|
int requestCode;
|
|
Intent cameraIntent;
|
|
response = Arguments.createMap();
|
|
|
|
if (!isCameraAvailable()) {
|
|
response.putString("error", "Camera not available");
|
|
callback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
Activity currentActivity = getCurrentActivity();
|
|
if (currentActivity == null) {
|
|
response.putString("error", "can't find current Activity");
|
|
callback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
parseOptions(options);
|
|
|
|
if (pickVideo == true) {
|
|
requestCode = REQUEST_LAUNCH_VIDEO_CAPTURE;
|
|
cameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
|
|
cameraIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, videoQuality);
|
|
if (videoDurationLimit > 0) {
|
|
cameraIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, videoDurationLimit);
|
|
}
|
|
} else {
|
|
requestCode = REQUEST_LAUNCH_IMAGE_CAPTURE;
|
|
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
|
|
// we create a tmp file to save the result
|
|
File imageFile = createNewFile(true);
|
|
mCameraCaptureURI = Uri.fromFile(imageFile);
|
|
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
|
|
|
|
if (allowEditing == true) {
|
|
cameraIntent.putExtra("crop", "true");
|
|
cameraIntent.putExtra("aspectX", aspectX);
|
|
cameraIntent.putExtra("aspectY", aspectY);
|
|
}
|
|
}
|
|
|
|
if (cameraIntent.resolveActivity(mReactContext.getPackageManager()) == null) {
|
|
response.putString("error", "Cannot launch camera");
|
|
callback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
mCallback = callback;
|
|
|
|
try {
|
|
currentActivity.startActivityForResult(cameraIntent, requestCode);
|
|
} catch (ActivityNotFoundException e) {
|
|
e.printStackTrace();
|
|
response = Arguments.createMap();
|
|
response.putString("error", "Cannot launch camera");
|
|
callback.invoke(response);
|
|
}
|
|
}
|
|
|
|
// NOTE: Currently not reentrant / doesn't support concurrent requests
|
|
@ReactMethod
|
|
public void launchImageLibrary(final ReadableMap options, final Callback callback) {
|
|
int requestCode;
|
|
Intent libraryIntent;
|
|
Activity currentActivity = getCurrentActivity();
|
|
|
|
if (currentActivity == null) {
|
|
response = Arguments.createMap();
|
|
response.putString("error", "can't find current Activity");
|
|
callback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
parseOptions(options);
|
|
|
|
if (pickVideo == true) {
|
|
requestCode = REQUEST_LAUNCH_VIDEO_LIBRARY;
|
|
libraryIntent = new Intent(Intent.ACTION_PICK);
|
|
libraryIntent.setType("video/*");
|
|
} else {
|
|
requestCode = REQUEST_LAUNCH_IMAGE_LIBRARY;
|
|
libraryIntent = new Intent(Intent.ACTION_PICK,
|
|
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
|
|
|
mCropImagedUri = null;
|
|
if (allowEditing == true) {
|
|
// create a file to save the croped image
|
|
File imageFile = createNewFile(true);
|
|
mCropImagedUri = Uri.fromFile(imageFile);
|
|
libraryIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCropImagedUri);
|
|
libraryIntent.putExtra("crop", "true");
|
|
libraryIntent.putExtra("aspectX", aspectX);
|
|
libraryIntent.putExtra("aspectY", aspectY);
|
|
}
|
|
}
|
|
|
|
if (libraryIntent.resolveActivity(mReactContext.getPackageManager()) == null) {
|
|
response = Arguments.createMap();
|
|
response.putString("error", "Cannot launch photo library");
|
|
callback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
mCallback = callback;
|
|
|
|
try {
|
|
currentActivity.startActivityForResult(libraryIntent, requestCode);
|
|
} catch (ActivityNotFoundException e) {
|
|
e.printStackTrace();
|
|
response = Arguments.createMap();
|
|
response.putString("error", "Cannot launch photo library");
|
|
callback.invoke(response);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
|
//robustness code
|
|
if (mCallback == null || (mCameraCaptureURI == null && requestCode == REQUEST_LAUNCH_IMAGE_CAPTURE)
|
|
|| (requestCode != REQUEST_LAUNCH_IMAGE_CAPTURE && requestCode != REQUEST_LAUNCH_IMAGE_LIBRARY
|
|
&& requestCode != REQUEST_LAUNCH_VIDEO_LIBRARY && requestCode != REQUEST_LAUNCH_VIDEO_CAPTURE)) {
|
|
return;
|
|
}
|
|
|
|
response = Arguments.createMap();
|
|
|
|
// user cancel
|
|
if (resultCode != Activity.RESULT_OK) {
|
|
response.putBoolean("didCancel", true);
|
|
mCallback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
Uri uri;
|
|
switch (requestCode) {
|
|
case REQUEST_LAUNCH_IMAGE_CAPTURE:
|
|
uri = mCameraCaptureURI;
|
|
break;
|
|
case REQUEST_LAUNCH_IMAGE_LIBRARY:
|
|
if (mCropImagedUri != null) {
|
|
uri = mCropImagedUri;
|
|
|
|
// we check if we get the uri in response if we get it the crop failed so mCropImagedUri point to
|
|
// an empty file
|
|
Uri uriTmp = data.getData();
|
|
if (uriTmp != null)
|
|
uri = uriTmp;
|
|
} else {
|
|
uri = data.getData();
|
|
}
|
|
break;
|
|
case REQUEST_LAUNCH_VIDEO_LIBRARY:
|
|
response.putString("uri", data.getData().toString());
|
|
response.putString("path", getRealPathFromURI(data.getData()));
|
|
mCallback.invoke(response);
|
|
return;
|
|
case REQUEST_LAUNCH_VIDEO_CAPTURE:
|
|
response.putString("uri", data.getData().toString());
|
|
response.putString("path", getRealPathFromURI(data.getData()));
|
|
mCallback.invoke(response);
|
|
return;
|
|
default:
|
|
uri = null;
|
|
}
|
|
|
|
String realPath = getRealPathFromURI(uri);
|
|
boolean isUrl = false;
|
|
|
|
if (realPath != null) {
|
|
try {
|
|
URL url = new URL(realPath);
|
|
isUrl = true;
|
|
} catch (MalformedURLException e) {
|
|
// not a url
|
|
}
|
|
}
|
|
|
|
// image isn't in memory cache
|
|
if (realPath == null || isUrl) {
|
|
try {
|
|
File file = createFileFromURI(uri);
|
|
realPath = file.getAbsolutePath();
|
|
uri = Uri.fromFile(file);
|
|
} catch (Exception e) {
|
|
// image not in cache
|
|
response.putString("error", "Could not read photo");
|
|
response.putString("uri", uri.toString());
|
|
mCallback.invoke(response);
|
|
return;
|
|
}
|
|
}
|
|
|
|
int CurrentAngle = 0;
|
|
try {
|
|
ExifInterface exif = new ExifInterface(realPath);
|
|
|
|
// extract lat, long, and timestamp and add to the response
|
|
float[] latlng = new float[2];
|
|
exif.getLatLong(latlng);
|
|
String latitude = Float.toString(latlng[0]);
|
|
String longitude = Float.toString(latlng[1]);
|
|
response.putString("latitude", latitude);
|
|
response.putString("longitude", longitude);
|
|
String timestamp = exif.getAttribute(ExifInterface.TAG_DATETIME);
|
|
response.putString("timestamp", timestamp);
|
|
|
|
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
|
|
boolean isVertical = true;
|
|
switch (orientation) {
|
|
case ExifInterface.ORIENTATION_ROTATE_270:
|
|
isVertical = false;
|
|
CurrentAngle = 270;
|
|
break;
|
|
case ExifInterface.ORIENTATION_ROTATE_90:
|
|
isVertical = false;
|
|
CurrentAngle = 90;
|
|
break;
|
|
case ExifInterface.ORIENTATION_ROTATE_180:
|
|
CurrentAngle = 180;
|
|
break;
|
|
}
|
|
response.putBoolean("isVertical", isVertical);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
response.putString("error", e.getMessage());
|
|
mCallback.invoke(response);
|
|
return;
|
|
}
|
|
|
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
|
options.inJustDecodeBounds = true;
|
|
Bitmap photo = BitmapFactory.decodeFile(realPath, options);
|
|
int initialWidth = options.outWidth;
|
|
int initialHeight = options.outHeight;
|
|
|
|
// don't create a new file if contraint are respected
|
|
if (((initialWidth < maxWidth && maxWidth > 0) || maxWidth == 0)
|
|
&& ((initialHeight < maxHeight && maxHeight > 0) || maxHeight == 0)
|
|
&& quality == 100 && (!forceAngle || (forceAngle && CurrentAngle == angle))) {
|
|
response.putInt("width", initialWidth);
|
|
response.putInt("height", initialHeight);
|
|
} else {
|
|
File resized = getResizedImage(realPath, initialWidth, initialHeight);
|
|
if (resized == null) {
|
|
response.putString("error", "Can't resize the image");
|
|
} else {
|
|
realPath = resized.getAbsolutePath();
|
|
uri = Uri.fromFile(resized);
|
|
photo = BitmapFactory.decodeFile(realPath, options);
|
|
response.putInt("width", options.outWidth);
|
|
response.putInt("height", options.outHeight);
|
|
}
|
|
}
|
|
|
|
response.putString("uri", uri.toString());
|
|
response.putString("path", realPath);
|
|
|
|
if (!noData) {
|
|
response.putString("data", getBase64StringFromFile(realPath));
|
|
}
|
|
|
|
putExtraFileInfo(realPath, response);
|
|
|
|
mCallback.invoke(response);
|
|
}
|
|
|
|
private boolean isCameraAvailable() {
|
|
return mReactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
|
|
|| mReactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
|
|
}
|
|
|
|
private String getRealPathFromURI(Uri uri) {
|
|
String result;
|
|
String[] projection = {MediaStore.Images.Media.DATA};
|
|
Cursor cursor = mReactContext.getContentResolver().query(uri, projection, null, null, null);
|
|
if (cursor == null) { // Source is Dropbox or other similar local file path
|
|
result = uri.getPath();
|
|
} else {
|
|
cursor.moveToFirst();
|
|
int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
|
result = cursor.getString(idx);
|
|
cursor.close();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Create a file from uri to allow image picking of image in disk cache
|
|
* (Exemple: facebook image, google image etc..)
|
|
*
|
|
* @doc =>
|
|
* https://github.com/nostra13/Android-Universal-Image-Loader#load--display-task-flow
|
|
*
|
|
* @param uri
|
|
* @return File
|
|
* @throws Exception
|
|
*/
|
|
private File createFileFromURI(Uri uri) throws Exception {
|
|
File file = new File(mReactContext.getCacheDir(), "photo-" + uri.getLastPathSegment());
|
|
InputStream input = mReactContext.getContentResolver().openInputStream(uri);
|
|
OutputStream output = new FileOutputStream(file);
|
|
|
|
try {
|
|
byte[] buffer = new byte[4 * 1024];
|
|
int read;
|
|
while ((read = input.read(buffer)) != -1) {
|
|
output.write(buffer, 0, read);
|
|
}
|
|
output.flush();
|
|
} finally {
|
|
output.close();
|
|
input.close();
|
|
}
|
|
|
|
return file;
|
|
}
|
|
|
|
private String getBase64StringFromFile(String absoluteFilePath) {
|
|
InputStream inputStream = null;
|
|
try {
|
|
inputStream = new FileInputStream(absoluteFilePath);
|
|
} catch (FileNotFoundException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
byte[] bytes;
|
|
byte[] buffer = new byte[8192];
|
|
int bytesRead;
|
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
try {
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
output.write(buffer, 0, bytesRead);
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
bytes = output.toByteArray();
|
|
return Base64.encodeToString(bytes, Base64.NO_WRAP);
|
|
}
|
|
|
|
/**
|
|
* Create a resized image to fill the maxWidth/maxHeight values,the quality
|
|
* value and the angle value
|
|
*
|
|
* @param realPath
|
|
* @param initialWidth
|
|
* @param initialHeight
|
|
* @return resized file
|
|
*/
|
|
private File getResizedImage(final String realPath, final int initialWidth, final int initialHeight) {
|
|
Bitmap photo = BitmapFactory.decodeFile(realPath);
|
|
|
|
if (photo == null) {
|
|
return null;
|
|
}
|
|
|
|
Bitmap scaledphoto = null;
|
|
if (maxWidth == 0) {
|
|
maxWidth = initialWidth;
|
|
}
|
|
if (maxHeight == 0) {
|
|
maxHeight = initialHeight;
|
|
}
|
|
double widthRatio = (double) maxWidth / initialWidth;
|
|
double heightRatio = (double) maxHeight / initialHeight;
|
|
|
|
double ratio = (widthRatio < heightRatio)
|
|
? widthRatio
|
|
: heightRatio;
|
|
|
|
Matrix matrix = new Matrix();
|
|
matrix.postRotate(angle);
|
|
matrix.postScale((float) ratio, (float) ratio);
|
|
|
|
ExifInterface exif;
|
|
try {
|
|
exif = new ExifInterface(realPath);
|
|
|
|
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
|
|
|
|
if (orientation == 6) {
|
|
matrix.postRotate(90);
|
|
} else if (orientation == 3) {
|
|
matrix.postRotate(180);
|
|
} else if (orientation == 8) {
|
|
matrix.postRotate(270);
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
scaledphoto = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(), photo.getHeight(), matrix, true);
|
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
|
scaledphoto.compress(Bitmap.CompressFormat.JPEG, quality, bytes);
|
|
|
|
File f = createNewFile(false);
|
|
FileOutputStream fo;
|
|
try {
|
|
fo = new FileOutputStream(f);
|
|
try {
|
|
fo.write(bytes.toByteArray());
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
} catch (FileNotFoundException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
// recycle to avoid java.lang.OutOfMemoryError
|
|
if (photo != null) {
|
|
scaledphoto.recycle();
|
|
photo.recycle();
|
|
scaledphoto = null;
|
|
photo = null;
|
|
}
|
|
return f;
|
|
}
|
|
|
|
/**
|
|
* Create a new file
|
|
*
|
|
* @return an empty file
|
|
*/
|
|
private File createNewFile(final boolean forcePictureDirectory) {
|
|
String filename = "image-" + UUID.randomUUID().toString() + ".jpg";
|
|
if (tmpImage && forcePictureDirectory != true) {
|
|
return new File(mReactContext.getCacheDir(), filename);
|
|
} else {
|
|
File path = Environment.getExternalStoragePublicDirectory(
|
|
Environment.DIRECTORY_PICTURES);
|
|
File f = new File(path, filename);
|
|
|
|
try {
|
|
path.mkdirs();
|
|
f.createNewFile();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return f;
|
|
}
|
|
}
|
|
|
|
private void putExtraFileInfo(final String path, WritableMap response) {
|
|
// size && filename
|
|
try {
|
|
File f = new File(path);
|
|
response.putDouble("fileSize", f.length());
|
|
response.putString("fileName", f.getName());
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
// type
|
|
String extension = MimeTypeMap.getFileExtensionFromUrl(path);
|
|
if (extension != null) {
|
|
response.putString("type", MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension));
|
|
}
|
|
}
|
|
|
|
private void parseOptions(final ReadableMap options) {
|
|
noData = false;
|
|
if (options.hasKey("noData")) {
|
|
noData = options.getBoolean("noData");
|
|
}
|
|
maxWidth = 0;
|
|
if (options.hasKey("maxWidth")) {
|
|
maxWidth = options.getInt("maxWidth");
|
|
}
|
|
maxHeight = 0;
|
|
if (options.hasKey("maxHeight")) {
|
|
maxHeight = options.getInt("maxHeight");
|
|
}
|
|
aspectX = 0;
|
|
if (options.hasKey("aspectX")) {
|
|
aspectX = options.getInt("aspectX");
|
|
}
|
|
aspectY = 0;
|
|
if (options.hasKey("aspectY")) {
|
|
aspectY = options.getInt("aspectY");
|
|
}
|
|
quality = 100;
|
|
if (options.hasKey("quality")) {
|
|
quality = (int) (options.getDouble("quality") * 100);
|
|
}
|
|
tmpImage = true;
|
|
if (options.hasKey("storageOptions")) {
|
|
tmpImage = false;
|
|
}
|
|
allowEditing = false;
|
|
if (options.hasKey("allowsEditing")) {
|
|
allowEditing = options.getBoolean("allowsEditing");
|
|
}
|
|
forceAngle = false;
|
|
angle = 0;
|
|
if (options.hasKey("angle")) {
|
|
forceAngle = true;
|
|
angle = options.getInt("angle");
|
|
}
|
|
pickVideo = false;
|
|
if (options.hasKey("mediaType") && options.getString("mediaType").equals("video")) {
|
|
pickVideo = true;
|
|
}
|
|
videoQuality = 1;
|
|
if (options.hasKey("videoQuality") && options.getString("videoQuality").equals("low")) {
|
|
videoQuality = 0;
|
|
}
|
|
videoDurationLimit = 0;
|
|
if (options.hasKey("durationLimit")) {
|
|
videoDurationLimit = options.getInt("durationLimit");
|
|
}
|
|
}
|
|
}
|