CB-6546 android: Fix a couple bugs with allowEdit pull request

- Don't set width/height when they are not specified
- photolibrary returns null from getData when image is cropped
This commit is contained in:
Andrew Grieve 2014-04-29 00:51:09 -04:00
parent c7d88e8b34
commit d899d7a4b8

View File

@ -60,7 +60,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
private static final int DATA_URL = 0; // Return base64 encoded string private static final int DATA_URL = 0; // Return base64 encoded string
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android) private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
private static final int NATIVE_URI = 2; // On Android, this is the same as FILE_URI private static final int NATIVE_URI = 2; // On Android, this is the same as FILE_URI
private static final int PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android) private static final int PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
private static final int CAMERA = 1; // Take picture from camera private static final int CAMERA = 1; // Take picture from camera
@ -95,14 +95,15 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
private MediaScannerConnection conn; // Used to update gallery app with newly-written files private MediaScannerConnection conn; // Used to update gallery app with newly-written files
private Uri scanMe; // Uri of image to be added to content store private Uri scanMe; // Uri of image to be added to content store
private Uri croppedUri;
/** /**
* Executes the request and returns PluginResult. * Executes the request and returns PluginResult.
* *
* @param action The action to execute. * @param action The action to execute.
* @param args JSONArry of arguments for the plugin. * @param args JSONArry of arguments for the plugin.
* @param callbackContext The callback id used when calling back into JavaScript. * @param callbackContext The callback id used when calling back into JavaScript.
* @return A PluginResult object with a status and message. * @return A PluginResult object with a status and message.
*/ */
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext; this.callbackContext = callbackContext;
@ -248,76 +249,85 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
public void getImage(int srcType, int returnType, int encodingType) { public void getImage(int srcType, int returnType, int encodingType) {
Intent intent = new Intent(); Intent intent = new Intent();
String title = GET_PICTURE; String title = GET_PICTURE;
croppedUri = null;
if (this.mediaType == PICTURE) { if (this.mediaType == PICTURE) {
intent.setType("image/*"); intent.setType("image/*");
if (this.allowEdit) { if (this.allowEdit) {
intent.setAction(Intent.ACTION_PICK); intent.setAction(Intent.ACTION_PICK);
intent.putExtra("crop", "true"); intent.putExtra("crop", "true");
if (this.targetHeight == this.targetWidth) { if (targetWidth > 0) {
intent.putExtra("aspectX", 1); intent.putExtra("outputX", targetWidth);
intent.putExtra("aspectY", 1); }
} if (targetHeight > 0) {
intent.putExtra("outputX", this.targetWidth); intent.putExtra("outputY", targetHeight);
intent.putExtra("outputY", this.targetHeight); }
File photo = createCaptureFile(encodingType); if (targetHeight > 0 && targetWidth > 0 && targetWidth == targetHeight) {
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, intent.putExtra("aspectX", 1);
Uri.fromFile(photo)); intent.putExtra("aspectY", 1);
} else { }
intent.setAction(Intent.ACTION_GET_CONTENT); File photo = createCaptureFile(encodingType);
intent.addCategory(Intent.CATEGORY_OPENABLE); croppedUri = Uri.fromFile(photo);
} intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, croppedUri);
} else if (this.mediaType == VIDEO) { } else {
intent.setType("video/*"); intent.setAction(Intent.ACTION_GET_CONTENT);
title = GET_VIDEO; intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setAction(Intent.ACTION_GET_CONTENT); }
intent.addCategory(Intent.CATEGORY_OPENABLE); } else if (this.mediaType == VIDEO) {
} else if (this.mediaType == ALLMEDIA) { intent.setType("video/*");
// I wanted to make the type 'image/*, video/*' but this does not work on all versions title = GET_VIDEO;
// of android so I had to go with the wildcard search. intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE);
title = GET_All; } else if (this.mediaType == ALLMEDIA) {
intent.setAction(Intent.ACTION_GET_CONTENT); // I wanted to make the type 'image/*, video/*' but this does not work on all versions
intent.addCategory(Intent.CATEGORY_OPENABLE); // of android so I had to go with the wildcard search.
} intent.setType("*/*");
title = GET_All;
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
}
if (this.cordova != null) { if (this.cordova != null) {
this.cordova.startActivityForResult((CordovaPlugin) this, Intent.createChooser(intent, this.cordova.startActivityForResult((CordovaPlugin) this, Intent.createChooser(intent,
new String(title)), (srcType + 1) * 16 + returnType + 1); new String(title)), (srcType + 1) * 16 + returnType + 1);
} }
} }
/** /**
* Brings up the UI to perform crop on passed image URI * Brings up the UI to perform crop on passed image URI
* *
* @param picUri * @param picUri
*/ */
private void performCrop(Uri picUri) { private void performCrop(Uri picUri) {
try { try {
Intent cropIntent = new Intent("com.android.camera.action.CROP"); Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri // indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*"); cropIntent.setDataAndType(picUri, "image/*");
// set crop properties // set crop properties
cropIntent.putExtra("crop", "true"); cropIntent.putExtra("crop", "true");
if (this.targetHeight == this.targetWidth) { // indicate output X and Y
cropIntent.putExtra("aspectX", 1); if (targetWidth > 0) {
cropIntent.putExtra("aspectY", 1); cropIntent.putExtra("outputX", targetWidth);
} }
// indicate output X and Y if (targetHeight > 0) {
cropIntent.putExtra("outputX", this.targetWidth); cropIntent.putExtra("outputY", targetHeight);
cropIntent.putExtra("outputY", this.targetHeight); }
// retrieve data on return if (targetHeight > 0 && targetWidth > 0 && targetWidth == targetHeight) {
cropIntent.putExtra("return-data", true); cropIntent.putExtra("aspectX", 1);
// start the activity - we handle returning in onActivityResult cropIntent.putExtra("aspectY", 1);
}
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
if (this.cordova != null) { if (this.cordova != null) {
this.cordova.startActivityForResult((CordovaPlugin) this, this.cordova.startActivityForResult((CordovaPlugin) this,
cropIntent, CROP_CAMERA); cropIntent, CROP_CAMERA);
} }
} catch (ActivityNotFoundException anfe) { } catch (ActivityNotFoundException anfe) {
Log.e(LOG_TAG, "Crop operation not supported on this device"); Log.e(LOG_TAG, "Crop operation not supported on this device");
// Send Uri back to JavaScript for viewing image // Send Uri back to JavaScript for viewing image
this.callbackContext.success(picUri.toString()); this.callbackContext.success(picUri.toString());
} }
} }
/** /**
* Applies all needed transformation to the image received from the camera. * Applies all needed transformation to the image received from the camera.
@ -410,11 +420,11 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
exif.writeExifData(); exif.writeExifData();
} }
if (this.allowEdit) { if (this.allowEdit) {
performCrop(uri); performCrop(uri);
} else { } else {
// Send Uri back to JavaScript for viewing image // Send Uri back to JavaScript for viewing image
this.callbackContext.success(uri.toString()); this.callbackContext.success(uri.toString());
} }
} }
// Send Uri back to JavaScript for viewing image // Send Uri back to JavaScript for viewing image
this.callbackContext.success(uri.toString()); this.callbackContext.success(uri.toString());
@ -459,6 +469,14 @@ private String ouputModifiedBitmap(Bitmap bitmap, Uri uri) throws IOException {
*/ */
private void processResultFromGallery(int destType, Intent intent) { private void processResultFromGallery(int destType, Intent intent) {
Uri uri = intent.getData(); Uri uri = intent.getData();
if (uri == null) {
if (croppedUri != null) {
uri = croppedUri;
} else {
this.failPicture("null data from photo library");
return;
}
}
int rotate = 0; int rotate = 0;
// If you ask for video or all media type you will automatically get back a file URI // If you ask for video or all media type you will automatically get back a file URI
@ -555,45 +573,49 @@ private String ouputModifiedBitmap(Bitmap bitmap, Uri uri) throws IOException {
int srcType = (requestCode / 16) - 1; int srcType = (requestCode / 16) - 1;
int destType = (requestCode % 16) - 1; int destType = (requestCode % 16) - 1;
// if camera crop // if camera crop
if (requestCode == CROP_CAMERA) { if (requestCode == CROP_CAMERA) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
// // get the returned data // // get the returned data
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
// get the cropped bitmap // get the cropped bitmap
Bitmap thePic = extras.getParcelable("data"); Bitmap thePic = extras.getParcelable("data");
if (thePic == null) {
this.failPicture("Crop returned no data.");
return;
}
// now save the bitmap to a file // now save the bitmap to a file
OutputStream fOut = null; OutputStream fOut = null;
File temp_file = new File(getTempDirectoryPath(), File temp_file = new File(getTempDirectoryPath(),
System.currentTimeMillis() + ".jpg"); System.currentTimeMillis() + ".jpg");
try { try {
temp_file.createNewFile(); temp_file.createNewFile();
fOut = new FileOutputStream(temp_file); fOut = new FileOutputStream(temp_file);
thePic.compress(Bitmap.CompressFormat.JPEG, this.mQuality, thePic.compress(Bitmap.CompressFormat.JPEG, this.mQuality,
fOut); fOut);
fOut.flush(); fOut.flush();
fOut.close(); fOut.close();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
// // Send Uri back to JavaScript for viewing image // // Send Uri back to JavaScript for viewing image
this.callbackContext this.callbackContext
.success(Uri.fromFile(temp_file).toString()); .success(Uri.fromFile(temp_file).toString());
}// If cancelled }// If cancelled
else if (resultCode == Activity.RESULT_CANCELED) { else if (resultCode == Activity.RESULT_CANCELED) {
this.failPicture("Camera cancelled."); this.failPicture("Camera cancelled.");
} }
// If something else // If something else
else { else {
this.failPicture("Did not complete!"); this.failPicture("Did not complete!");
} }
} }
// If CAMERA // If CAMERA
if (srcType == CAMERA) { if (srcType == CAMERA) {
// If image available // If image available
@ -961,4 +983,4 @@ private String ouputModifiedBitmap(Bitmap bitmap, Uri uri) throws IOException {
public void onScanCompleted(String path, Uri uri) { public void onScanCompleted(String path, Uri uri) {
this.conn.disconnect(); this.conn.disconnect();
} }
} }