so this was working lovely till yesterday when I upgraded my phone to 5.0.0 and tested the application out in a 5.0.0 emulator. Basically the purpose is to allow the user to take a photo, return it, open it to allow cropping then return it and set it as an imageview.
Everything worked fine before but now the intent in onActivityResult is null.
Here's code:
public void takeDisplayPicture(View view) {
final String TAKE_DISPLAY_PICTURE = "Take Display Picture";
Log.d(TAKE_DISPLAY_PICTURE, "Clicked");
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_CAPTURE);
} catch (ActivityNotFoundException e) {
String msg = "Your device doesn't support a camera!";
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final String RETURN_DISPLAY_PICTURE = "Return Display Picture";
Log.d(RETURN_DISPLAY_PICTURE, "Returned");
if (resultCode == RESULT_OK && requestCode == CAMERA_CAPTURE) {
picUri = data.getData();
performCrop(picUri);
} else if (requestCode == PIC_CROP) {
Bundle extras = data.getExtras();
bitmap = extras.getParcelable("data");
displayPicture.setImageBitmap(bitmap);
}
}
private void performCrop(Uri picUri) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
} catch (ActivityNotFoundException e) {
String msg = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
First, Android does not have a CROP Intent.
With respect to the null Uri, it is supposed to be null. Quoting the ACTION_IMAGE_CAPTURE documentation:
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field.
You do not have EXTRA_OUTPUT, and so you are supposed to get your image via the poorly-documented (Bitmap)data.getExtras().get("data");.
Related
how to get uri from Bitmap after cropping image was selected from gallery
i tried this
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
but uri = null
i want to get uri from this
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
Uri imageUri = data.getData();
performCrop(imageUri);
Log.e(TAG, "image before crop:" + imageUri);
}else if(resultCode == Activity.RESULT_OK && requestCode == PIC_CROP ){
// get the returned data
Bundle extras = data.getExtras();
// get the cropped bitmap
Bitmap selectedBitmap = extras.getParcelable("data");
getImageUri(this,selectedBitmap);
Uri ImageUri = data.getData();
Log.e(TAG, "image before crop:" + ImageUri);
log image before crop=null
---- UPDATE CROPPING----
private void performCrop(Uri picUri) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*");
// set crop properties here
cropIntent.putExtra("crop", true);
// indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
// indicate output X and Y
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 128);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, PIC_CROP);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
// display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
Im guessing you are selecting an image from your gallery.
perquisites:
Permissions in manifest to read/write data
Validation of permissions and handle no permissions granted case
Request code declared:
public static final int PICK_IMAGE = 1050;
(1)
Open image selector activity
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
In Activity:
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
In Fragment:
fragment.startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
(2) retrieving image from selection:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(resultCode == RESULT_OK && data != null && data.getData() != null ){
switch(requestCode){
case PICK_IMAGE_REQUEST:
//get filepath from the result of image selection
Uri filePath = data.getData();
//Start activity for result for crop for selected image
startCropActivity(filePath);
break;
case PIC_CROP:
// get the returned data
Bundle extras = data.getExtras();
// get the cropped bitmap
Bitmap selectedBitmap = extras.getParcelable("data");
//do whatever with the bitmap of the image
break;
}
}
}
Start Crop activity as so:
private void startCropActivity(Uri filePath){
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(filePath, "image/*");
cropIntent.putExtra("crop", true);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 128);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
}catch (ActivityNotFoundException anfe) {
// display an error message
Toast.makeText(this, "Could not crop", Toast.LENGTH_SHORT).show();
}
}
i'm writing an android app on java and need to let my users select and crop images from the gallery.
There is no problem when choosing an image from any native gallery, but when a user chooses to eater crop or choose an image from google photos app the app crushes.
I cannot figure out what is the source of the problem so any answer will be helpful
this is the code i'm using
class fields:
private Uri imageUri;
opening the camera:
private void camOpen() {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory(), "file" + String.valueOf(System.currentTimeMillis()) + ".png");
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
imageUri = Uri.fromFile(f);
i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
i.putExtra("return-data", true);
startActivityForResult(i, CAMERA_CODE);
}
opening the gallery:
private void galleryOpen() {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(i, "select file"), SELECT_PHOTO_CODE);
}
cropping the image:
private void cropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(imageUri, "image/*");
cropIntent.putExtra("crop", true);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, CROP_CODE);
} catch (Exception e) {}
}
the result handler:
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_CODE && resultCode == Activity.RESULT_OK) {
cropImage();
} else if (requestCode == SELECT_PHOTO_CODE && resultCode == Activity.RESULT_OK) {
if (data != null) {
imageUri = data.getData();
cropImage();
}
} else if (requestCode == CROP_CODE && resultCode == Activity.RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap b = bundle.getParcelable("data");
hasImageChanged=true;
ivProfilePic.setImageBitmap(b);
capturedImage = b;
}
}
thank you for any useful help...
Android does not support crop intent because croping is not part of android api.
So i recommend you for Using library
the issue was with the crop intent. I ended up using the uCrop library and it fixed the problem.
When i press the button then the camera captures the picture, I want to perform crop on that picture after Cropping but i am unable to figure out the problem because crop function is not working properly, Please Help me to figure out the problem that is the main cause of crop function is not being preformed
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
final int CAMERA_CAPTURE = 1;
final int CROP_PIC = 2;
private Uri picUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button captureBtn = (Button) findViewById(R.id.capture_btn);
captureBtn.setOnClickListener((View.OnClickListener) this);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.capture_btn) {
try {
// use standard intent to capture an image
Intent captureIntent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
// we will handle the returned data in onActivityResult
startActivityForResult(captureIntent, CAMERA_CAPTURE);
} catch (ActivityNotFoundException anfe) {
Toast toast = Toast.makeText(this, "This device doesn't support the crop action!",
Toast.LENGTH_SHORT);
toast.show();
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast toast4 = Toast.makeText(this, Integer.toString(RESULT_OK),
Toast.LENGTH_SHORT);
toast4.show();
if (resultCode == RESULT_OK) {
Toast toast = Toast.makeText(this, "capture ok",
Toast.LENGTH_SHORT);
toast.show();
if (requestCode == CAMERA_CAPTURE) {
// get the Uri for the captured image
picUri = data.getData();
// Toast toast1 = Toast.makeText(this, Integer.toString(requestCode),
// Toast.LENGTH_SHORT);
// toast1.show();
performCrop();
}
// user is returning from cropping the image
if (requestCode == CROP_PIC) {
Toast toast1 = Toast.makeText(this, "crop ok",
Toast.LENGTH_SHORT);
toast1.show();
// get the returned data
Bundle extras = data.getExtras();
// get the cropped bitmap
Bitmap thePic = extras.getParcelable("data");
ImageView picView = (ImageView) findViewById(R.id.picture);
picView.setImageBitmap(thePic);
}
}
}
/**
* this function does the crop operation.
*/
private void performCrop() {
////////////////// take care of exceptions
try {
// call the standard crop action intent (the user device may not
// support it)
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*");
// set crop properties
cropIntent.putExtra("crop", "true");
// indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
// indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_PIC);
}
catch (ActivityNotFoundException anfe) {
Toast toast3 = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast3.show();
}
}
}
I'm trying to capture an image from the Android Camera/ Pick an image from the gallery and then crop it before performing other operations on it. I'm having trouble with getting back the URI of the cropped image. Any help on how to get back the URI of the image once it has been cropped would be much appreciated!
The code below pertains to my onActivityResult and my function performing the crop
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE || requestCode == REQUEST_IMAGE_CAPTURE) {
if(!IS_CAMERA_USED) {
selectedImageUri = data.getData();
}
performCrop();
}
else if(requestCode == CROP_IMAGE){
selectedImageUri = data.getData();
onSelectedImageResult();
}
}
}
public void performCrop() {
// take care of exceptions
Display display = getWindowManager().getDefaultDisplay();
try {
// call the standard crop action intent (the user device may not
// support it)
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(selectedImageUri, "image/*");
// set crop properties
cropIntent.putExtra("crop", "true");
// indicate aspect of desired crop
cropIntent.putExtra("aspectY", 1);
if(IS_PROFILE_PICTURE) {
cropIntent.putExtra("aspectX", 1);
}
else {
cropIntent.putExtra("aspectX", 2);
}
// indicate output X and Y
cropIntent.putExtra("outputX", display.getWidth());
cropIntent.putExtra("outputY", display.getHeight());
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
Toast toast = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
}
}
The problem is in the line selectedImageUri = data.getData(), where data.getData() returns null after having done the crop. How do I get back the URI of the cropped image? I don't want to get data.getExtras.getParcelable("data") as that returns the thumbnail and ruins the image resolution.
Thanks in advance!
You can get the image bitmap with this code:
if (requestCode == CROP_IMAGE) {
if (data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap selectedBitmap = extras.getParcelable("data");
//imgView.setImageBitmap(selectedBitmap);
}
}
}
URI is not possible I think, because the cropped image is not saved on the storage.
Thanks for all your answers, but I found something way simpler to incorporate and use that avoids all hassles due to the `com.android.camera.action.CROP' class, and it can be found here
I think that you should save the cropped Bitmap to your storage, and then use the URI of the cropped Bitmap to performe something over it!
I know it's not a professional work but at least it should do it
I'm currently working on the user profile for my app. Up until recently, I've been testing on a Samsung Galaxy Note 4, which hasn't been giving me any problems with the code below. In later testing, however, I got my hands on a Nexus 5x, and when I use the below code to try and select a user profile image, I get the error "Unfortunately Photos has stopped". I don't have any error logs, since I am unable to debug Photos.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case 0:
if(resultCode == RESULT_OK){
Uri selectedImage = data.getData();
cropImage(selectedImage);
}
break;
case 1:
if(resultCode == RESULT_OK){
Uri selectedImage = data.getData();
cropImage(selectedImage);
}
break;
case 2:
if(resultCode == RESULT_OK){
Uri selectedImage = data.getData();
profileImage.setImageURI(selectedImage);
try {
userProfileImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
AlmightyFunctions.ImageService.saveProfileImage(user,userProfileImage);
}
catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
public void showImageSelectDialog() {
CharSequence options[] = new CharSequence[] {
getString(R.string.select_camera),
getString(R.string.select_gallery)
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.select_image_dialog));
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
MarshMallowPermission mmp = new MarshMallowPermission(UserProfileActivity.this);
switch(which) {
case 0:
if (!mmp.checkPermissionForCamera()) {
mmp.requestPermissionForCamera();
}
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, 0);
break;
case 1:
if (!mmp.checkPermissionForExternalStorage()) {
mmp.requestPermissionForExternalStorage();
}
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto, 1);
break;
}
}
});
builder.show();
}
public void cropImage(Uri photoUri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(photoUri, "image/*"); // this will open all images in the Gallery
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1); // this defines the aspect ration
intent.putExtra("aspectY", 1);
intent.putExtra("return-data", true); // true to return a Bitmap, false to directly save the cropped iamge
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); //save output image in uri
startActivityForResult(intent,2);
}
Any help would be greatly appreciated.
Android does not have a CROP Intent. Your code will fail on hundreds of millions of devices.
There are many image cropping libraries available for Android. Please use one.