I have 3 activities say A, B and C.
A calls B.
When B doesn't call C it returns to A. But when B calls C it doesn't return to A, the app stops.
Now the real problem is, from activity A I want to call an image picker and crop the image. That's Activity B which crops and calls C for picking image.
Activity A:
iv_profile_pic.setOnClickListener(new View.OnClickListener() {//iv_profile_pic is an ImageView
#Override
public void onClick(View view) {
Intent i=new Intent(MainActivity.this,profile_pic_chooser.class);
i.setFlags(0);
MainActivity.this.startActivityForResult(i, 999);
Toast.makeText(getApplicationContext(),"Reached",Toast.LENGTH_SHORT).show();
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 999) {
Bitmap image=data.getParcelableExtra("picture");
iv_profile_pic.setImageBitmap(image);
}
}
Activity B:
It has 2 buttons. Load and Crop. Load when clicked calls ImageChooserIntent and chooses an image which is opened in B with guidlines to crop.
Crop when clicked should return back to A the cropped image.
If crop is called without calling load, it returns to A with null, of-course.
But if Load is clicked first and then Crop is called, the app simply stops.
public void onLoadImageClick(View view) {
startActivityForResult(getPickImageChooserIntent(), 200);
}
public void onCropImageClick(View view) {
Bitmap cropped = mCropImageView.getCroppedImage(500, 500);
if (cropped != null) {
mCropImageView.setImageBitmap(cropped);
iv.setImageBitmap(cropped);
Intent returnIntent = new Intent();
returnIntent.putExtra("picture", cropped);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri imageUri = getPickImageResultUri(data);
// For API >= 23 we need to check specifically that we have permissions to read external storage,
// but we don't know if we need to for the URI so the simplest is to try open the stream and see if we get error.
boolean requirePermissions = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
isUriRequiresPermissions(imageUri)) {
// request permissions and handle the result in onRequestPermissionsResult()
requirePermissions = true;
mCropImageUri = imageUri;
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}
if (!requirePermissions) {
mCropImageView.setImageUriAsync(imageUri);
}
}
}
I got a workaround. The most probable problem I was facing was:
I was using an external library for cropping the image. This library did 2 things.
First, selected an image using imageChooser intent.
Second, Cropped that image.
After the library cropped the image, it wasn't saving the cropped image in local/external storage. But I was trying to pass it back to parent directory.
There's the problem. The file doesn't exist and still I am trying to use it. The application terminates.
So my workaround was,
• Save the bitmap in storage
• Pass the Uri to parent
• Extract that Uri from child
• Make bitmap from that Uri
• Apply on the ImageView
So Activity B had:
public void onCropImageClick(View view) {
Bitmap cropped = mCropImageView.getCroppedImage(500, 500);
if (cropped != null) {
mCropImageView.setImageBitmap(cropped);
iv.setImageBitmap(cropped);
File externalStorageDirectory = Environment.getExternalStorageDirectory();
externalStorageDirectory= new File(externalStorageDirectory , "FOLDERNAME");
if(!createDirIfNotExists(externalStorageDirectory)){
Toast.makeText(this,"Failed creating Directory!",Toast.LENGTH_SHORT).show();
}else{
File filename=new File(externalStorageDirectory, String.valueOf(Calendar.getInstance().getTimeInMillis())+".PNG");
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
cropped.compress(Bitmap.CompressFormat.PNG, 100, out); // cropped is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
Intent returnIntent = new Intent();
returnIntent.putExtra("picture", Uri.fromFile(filename));
setResult(RESULT_OK, returnIntent);
finish();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//Toast.makeText(this,mCropImageUri.toString(),Toast.LENGTH_SHORT).show();
}
And Activity A had:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 999 && resultCode==RESULT_OK) {
Uri path=data.getParcelableExtra("picture");
Bitmap bitmap=null;
try {
bitmap= MediaStore.Images.Media.getBitmap(this.getContentResolver(), path);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(this,path.toString(),Toast.LENGTH_SHORT).show();
if (bitmap!=null){
iv_profile_pic.setImageBitmap(bitmap);
}
}
Maybe my problem statement is wrong, but workaround works. Any edits/suggestions
are 100% welcome. Just in-case someone like me gets stuck, this might help!
Related
Hi I want to capture image and do some opration for that image in my next activity.I have tried to run the below code in Samsung and Moto G and its working fine.When I tried same code with redmi note3,after Clicking right mark it is coming to the same activity.How to solve this? This is my code:
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri outputFileUri = Uri.fromFile(originalFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No camera app found!", Toast.LENGTH_LONG).show();
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
Bitmap imageData = null;
if (resultCode ==Activity.RESULT_OK) {
try
{
BitmapFactory.Options bitopt=new BitmapFactory.Options();
imageData = BitmapFactory.decodeFile(imagePath, bitopt);
Uri tempUri = getImageUri(getApplicationContext(), imageData);
Intent i = new Intent(this, Image_R.class);
i.putExtra("imageUri", tempUri.toString());
startActivityForResult(i, 3);
}
catch (Exception e) {
Toast.makeText(this, "Unable to save image", Toast.LENGTH_LONG).show();
}
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
}
}
replace this:--
i.putExtra(MediaStore.EXTRA_OUTPUT, MyFileContentProvider.CONTENT_URI);
Add this code to your activity tag inside your Manifest file.
android:configChanges="orientation|keyboardHidden|screenSize"
It will not let your current activity to destroy and re-create so you will get the result.
And if this doesn't work make sure that your Device is not on power/battery saving mode.
RedMi devices with active power/battery saving mode cause previous activity to lose it's state and when coming back for result it will call onCreate again so you won't get the true result.
I'm working on an app which allows user to choose a picture from gallery and then I start a activity to crop it.
I want to send the cropped image back to calling activity.
Both activities extend AppCompatActivity.
Calling activity:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
// start image crop activity
String dataString = data.getDataString();
Intent intent=new Intent(this, CropPhotoActivity.class);
intent.putExtra("SELECTED_PICTURE_FOR_CROP", dataString);
startActivityForResult(intent, CROP_PICTURE);
}
else if(requestCode == CROP_PICTURE) {
// get cropped bitmap
Bitmap bitmap = (Bitmap) data.getParcelableExtra("CROPPED_IMAGE");
profilePhoto.setImageBitmap(bitmap);
}
}
}
In the crop image activity, I have a button, which on click should return back to calling activity:
Button okButton = (Button)findViewById(R.id.ok_button);
okButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent returnIntent = new Intent();
returnIntent.putExtra("CROPPED_IMAGE", cropped_bitmap);
setResult(RESULT_OK, returnIntent);
finish(); // sometimes restarts app
}
});
Sometimes the bitmap gets returned correctly whereas sometimes it does not and the app gets restarted without error. Why is this happening? Does putExtra have anything to do with bitmap size or anything else?
You could try substituting
AppcompatActivity.this.finish()
(where AppcompatActivity is your class name)
for:
finish(); // sometimes restarts app
Or, create a method in the calling Activity:
public static void cropComplete(Activity activity)
{
activity.startActivity(activity, AnotherActivity.class);
activity.finish();
}
Theres's a limit for data length passed as extra in a intent. Try not passing the dataString value; instead you should save the image as a temporary file, pass the path in the intent and then load the image from your calling activity (or you can just save the dataString in a static helper class).
In the crop activity (saving bitmap code from Save bitmap to location):
// Save bitmap
String filename = "tempImage.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
FileOutputStream out = null;
try {
out = new FileOutputStream(dest);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null)out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Get image file path
String path = dest.getAbsolutePath();
// Set result with image path
Intent returnIntent = new Intent();
returnIntent.putExtra("CROPPED_IMAGE_PATH", path);
setResult(RESULT_OK, returnIntent);
finish();
In the caller activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(requestCode == CROP_PICTURE) {
// Get image file path
String imagePath = data.getStringExtra("CROPPED_IMAGE_PATH");
// Load image
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
}
}
I've looked through tons of posts and cannot figure out why I can't get this to work. All I want to do is have the user click a button that opens up the gallery app. Then the user selects a picture which automatically closes out the gallery and goes back to my application where it automatically sets that image to an ImageView.
So far, I have it working all the way up until it goes back to my application. It seems to all be fine but the image never shows up in the ImageView.
Here is the XML code for the ImageView:
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:layout_gravity="center_horizontal" />
At the beginning of my activity I set the ImageView with this:
ImageView targetImage;
And here is the rest of my code to get the image and set it to my ImageView. There is a button that launches "setGunImage".
public void setGunImage(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
targetImage = (ImageView)findViewById(R.id.imageView1);
Uri selectedImageUri = data.getData();
targetImage.setImageURI(selectedImageUri);
}
}
}
I have tested it on both the simulator with the sd card enabled and an image loaded into and also on a real device. Both give the same behavior. It goes through the gallery steps fine but when it goes back to my application there is no image loaded in the ImageView.
I tried changing the data to a bitmap and setting that but it never showed up either. I know it's probably something super simple that I'm just not seeing so hopefully a fresh pair of eyes can point me in the right direction. Thanks.
I think Imran solution should work fine .............. and you can also try this way
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
InputStream stream = null;
if( resultCode==RESULT_OK)
{
if(requestCode==SELECT_PICTURE)
{
try {
// We need to recyle unused bitmaps
if (bitmap != null) {
bitmap.recycle();
}
stream = getContentResolver().openInputStream(data.getData());
bitmap = BitmapFactory.decodeStream(stream);
targetImage = (ImageView)findViewById(R.id.imageView1);
targetImage.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
from link
you are passing URI in setImageURI so fist get path of image using MediaStore.Images.Media.DATA and URI then pass path of image in setImageURI.
try this way:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if( resultCode==RESULT_OK)
{
if(requestCode==SELECT_PICTURE)
{
targetImage = (ImageView)findViewById(R.id.imageView1);
Uri selectedImageUri = data.getData();
String selectedImagePath=getPath(selectedImageUri);
targetImage.setImageURI(selectedImageUri);
}
}
}
private String getPath(Uri uri)
{
String[] projection={MediaStore.Images.Media.DATA};
Cursor cursor=managedQuery(uri,projection,null,null,null);
int column_index=cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I have an app published and one of the fundamental features is to allow the user to take a picture, and then save that photo in a specific folder on their External Storage.
Everything seems to be working fine, but I've gotten two reports now that claim that after taking a photo, and clicking "Done" to exit the camera (and return back to the Activity), the app is Forced Closed, bringing the user back to the home screen.
This happens on a Samsung Nexus S and the Galaxy Tab. Below I've posted my code to show I set up my intent and how I handle saving and displaying the photo in onActivityResult(). Any guidance on what might be causing it to crash after they click "Done" to exit the camera app, would be greatly appreciated!
Again, this seems to be working fine on most devices but I was wondering if their is a more efficient, universal approach I should be taking. Thank you
How I'm firing the Camera Intent
case ACTION_BAR_CAMERA:
// numbered image name
fileName = "image_" + String.valueOf(numImages) + ".jpg";
output = new File(direct + File.separator + fileName); // create
// output
while (output.exists()) { // while the file exists
numImages++; // increment number of images
fileName = "image_" + String.valueOf(numImages) + ".jpg";
output = new File(outputFolder, fileName);
}
camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
uriSavedImage = Uri.fromFile(output); // get Uri of the output
camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); //pass in Uri to camera intent
startActivityForResult(camera, 1);
break;
default:
return super.onHandleActionBarItemClick(item, position);
}
return true;
}
How I'm setting up onActivityResult()
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) { // If data was passed successfully
Bundle extras = data.getExtras();
//Bundle extras = data.getBundleExtra(MediaStore.EXTRA_OUTPUT);
/*ad = new AlertDialog.Builder(this).create();
ad.setIcon(android.R.drawable.ic_menu_camera);
ad.setTitle("Save Image");
ad.setMessage("Save This Image To Album?");
ad.setButton("Ok", this);
ad.show();*/
bmp = (Bitmap) extras.get("data"); // Set the bitmap to the bundle
// of data that was just
// received
image.setImageBitmap(bmp); // Set imageview to image that was
// captured
image.setScaleType(ScaleType.FIT_XY);
}
}
First lets make it clear - we have two options to take image data in onActivityResult from Camera:
1. Start Camera by passing the exact location Uri of image where you want to save.
2. Just Start Camera don't pass any Loaction Uri.
1 . IN FIRST CASE :
Start Camera by passing image Uri where you want to save:
String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg";
File imageFile = new File(imageFilePath);
Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri
Intent it = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
it.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(it, CAMERA_RESULT);
In onActivityResult receive the image as:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RESULT_OK == resultCode) {
iv = (ImageView) findViewById(R.id.ReturnedImageView);
// Decode it for real
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = false;
//imageFilePath image path which you pass with intent
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
// Display it
iv.setImageBitmap(bmp);
}
}
2 . IN SECOND CASE:
Start Camera without passing image Uri, if you want to receive image in Intent(data) :
Intent it = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(it, CAMERA_RESULT);
In onActivityResult recive image as:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RESULT_OK == resultCode) {
// Get Extra from the intent
Bundle extras = data.getExtras();
// Get the returned image from extra
Bitmap bmp = (Bitmap) extras.get("data");
iv = (ImageView) findViewById(R.id.ReturnedImageView);
iv.setImageBitmap(bmp);
}
}
*****Happy Coding!!!!*****
On the camera button click event you can try this:
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getTempFile(this)));
startActivityForResult(intent, TAKE_PHOTO_CODE);
declare TAKE_PHOTO_CODE globally as:
private static final int TAKE_PHOTO_CODE = 1;
Add getTempFile Function in the code which will help to save the image named myImage.png you clicked in the sdcard under the folder named as your app's package name.
private File getTempFile(Context context) {
final File path = new File(Environment.getExternalStorageDirectory(),
context.getPackageName());
if (!path.exists()) {
path.mkdir();
}
return new File(path, "myImage.png");
}
Now on OnActivityResult function add this:
if (requestCode == TAKE_PHOTO_CODE) {
final File file = getTempFile(this);
try {
Uri uri = Uri.fromFile(file);
Bitmap captureBmp = Media.getBitmap(getContentResolver(),
uri);
image.setImageBitmap(captureBmp);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
in case you get Memory issues than add below code:
#Override
protected void onPause() {
image.setImageURI(null);
super.onPause();
}
I hope this will help you
I suspect 3 posible problems may have created your issue:
Some devices return null when you call extras.get("data"); in onActivityResult method so your problem may be a NullPointerException. To solve this, you need to pass the exact URI location to tell the camera app where you want it to store and use it in onActivityResult to retrieve the image as a Bitmap.
Some other devices return a full size Bitmap when extras.get("data"); in onActivityResult. If the bitmap is too large that can result in an OutOfMemmoryError, so maybe you need to decode your image in a smaller size to not take so much memmory heap. This two links can help you in this situation:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
BitmapFactory OOM driving me nuts
Maybe your activity is destroyed by the GC so you have to use onSavedInstanceState and onRestoreInstanceState to save your Activity's data. See the answer of this previous post for more information.
I don't know if you already have dealt with these issues.
Hope that helps:)
First, make sure to check request code, you might be catching someone else's result there. Second, don't use the intent's data Bitmap - if anything, it's small, but since you provide the path to store captured image, it shouldn't even be there (see here). So, store the url you provided as output file path and read Bitmap from there when you've received RESULT_OK for your request:
...
// save your file uri, not necessarily static
mUriSavedImage = Uri.fromFile(output);
startActivityForResult(camera, MY_REQUEST_CODE);
/* Make a String like "com.myname.MY_REQUEST_CODE" and hash it into int to give it
a bit of uniqueness */
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bitmap bmp = BitmapFactory.decodeFile(mUriSavedImage);
if (bmp != null) {
image.setImageBitmap(bmp); // Set imageview to image that was
// captured
image.setScaleType(ScaleType.FIT_XY);
} else {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
For Samsung devices add below one line in your AndroidManifest.xml File
android:configChanges="orientation|screenSize"
i hope this will work for you
I faced the same issue. Apparently the fix is to make the uriSavedImage as static. Not sure if this is the best way. But this works for me.
Follow the steps given on this link. Hope this is useful for you.
OR
Fetching Your Image Without Crashing
Write the below code in MainActivity
// Storage for camera image URI components
private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath";
private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI";
// Required for camera operations in order to save the image file on resume.
private String mCurrentPhotoPath = null;
private Uri mCapturedImageURI = null;
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
if (mCurrentPhotoPath != null) {
savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath);
}
if (mCapturedImageURI != null) {
savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString());
}
super.onSaveInstanceState(savedInstanceState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) {
mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY);
}
if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) {
mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY));
}
super.onRestoreInstanceState(savedInstanceState);
}
Hello all i know answer has been given but as this is also one of the easiest solution solution i have ever found
Here is an example, which is itself bothering about the device!
AndroidCameraUtils - Download the project and from library project by including it below is the code snippet you can use !
private void setupCameraIntentHelper() {
mCameraIntentHelper = new CameraIntentHelper(this, new CameraIntentHelperCallback() {
#Override
public void onPhotoUriFound(Date dateCameraIntentStarted, Uri photoUri, int rotateXDegrees) {
messageView.setText(getString(R.string.activity_camera_intent_photo_uri_found) + photoUri.toString());
Bitmap photo = BitmapHelper.readBitmap(CameraIntentActivity.this, photoUri);
if (photo != null) {
photo = BitmapHelper.shrinkBitmap(photo, 300, rotateXDegrees);
ImageView imageView = (ImageView) findViewById(de.ecotastic.android.camerautil.sample.R.id.activity_camera_intent_image_view);
imageView.setImageBitmap(photo);
}
}
#Override
public void deletePhotoWithUri(Uri photoUri) {
BitmapHelper.deleteImageWithUriIfExists(photoUri, CameraIntentActivity.this);
}
#Override
public void onSdCardNotMounted() {
Toast.makeText(getApplicationContext(), getString(R.string.error_sd_card_not_mounted), Toast.LENGTH_LONG).show();
}
#Override
public void onCanceled() {
Toast.makeText(getApplicationContext(), getString(R.string.warning_camera_intent_canceled), Toast.LENGTH_LONG).show();
}
#Override
public void onCouldNotTakePhoto() {
Toast.makeText(getApplicationContext(), getString(R.string.error_could_not_take_photo), Toast.LENGTH_LONG).show();
}
#Override
public void onPhotoUriNotFound() {
messageView.setText(getString(R.string.activity_camera_intent_photo_uri_not_found));
}
#Override
public void logException(Exception e) {
Toast.makeText(getApplicationContext(), getString(R.string.error_sth_went_wrong), Toast.LENGTH_LONG).show();
Log.d(getClass().getName(), e.getMessage());
}
});
}
#Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
mCameraIntentHelper.onSaveInstanceState(savedInstanceState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCameraIntentHelper.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
mCameraIntentHelper.onActivityResult(requestCode, resultCode, intent);
}
}
NOTE:- I tried many examples for camera utils and ofcourse there are another ways to handle it but for beginners and person who are not too much familier with the core concepts would be more comfort with this project. THanks!
<!-- User features are request to enroll due to vivo solution for mobiles-->
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.front" android:required="true" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="true"/>
<uses-feature android:name="android.hardware.microphone" />
<uses-feature
android:name="android.hardware.camera.any"
android:required="true"/>
<uses-feature
android:name="android.hardware.camera.flash"
android:required="true"/>
<!-- end User features are request to enroll due to vivo solution for mobiles-->
I'm using a photo picker intent to choose an image and write it to an application-private file. Most of my important source code is shown below. Once I press a button and perform the first image selection intent, then it successfully updates the image view. However, once I press the image selection button again (in the same activity), then the image view does NOT update, unless I exit and restart the activity. So I know the image is getting successfully saved, but why would the ImageView in the layout not refresh or update?
public void onResume() {
super.onResume();
ImageView myImageView = (ImageView)findViewById(R.id.contact_image);
if (hasImage) {
myImageView.setImageURI(Uri.fromFile(getFileStreamPath(TEMP_PHOTO_FILE)));
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PHOTO_PICKED:
if (resultCode == RESULT_OK) {
if (data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
hasImage = true;
bmp = (Bitmap) extras.get("data");
}
}
}
break;
}
}
private OnClickListener mChooseImage = new OnClickListener() {
#Override
public void onClick(View v) {
try {
// Launch picker to choose photo for selected contact
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", ICON_SIZE);
intent.putExtra("outputY", ICON_SIZE);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile()));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, PHOTO_PICKED);
} catch (ActivityNotFoundException e) {
// LOG THIS
}
}
};
private File getTempFile() {
try {
if (!hasImage) {
FileOutputStream fos = openFileOutput(TEMP_PHOTO_FILE, MODE_WORLD_WRITEABLE);
fos.close();
}
return getFileStreamPath(TEMP_PHOTO_FILE);
} catch (FileNotFoundException e) {
// To be logged later
return null;
} catch (IOException e) {
// To be logged later
return null;
}
}
upon activity result, I set the ImageView's image URI to this file.
When it first completes, the ImageView changes to reflect this. However, if I attempt to choose the image again (same activity), the ImageView will not update until I exit and re-enter the activity. I'm not sure why this happens, is it because I'm trying to write to the temp.jpg everytime? Or do I need to refresh my layout somehow to reflect changes in the ImageView?
Judging by the ImageView source code, the ImageView won't reload the image if you call setImageURI with the same URI. You could try changing the URI by writing your image to another file.
ImageView will not redraw if "new" URI is the same like old one. "View.invalidate()" will not work. To "force" update you can do:
public void onResume() {
super.onResume();
ImageView myImageView = (ImageView)findViewById(R.id.contact_image);
if (hasImage) {
myImageView.setImageDrawable(null); // <--- added to force redraw of ImageView
myImageView.setImageURI(Uri.fromFile(getFileStreamPath(TEMP_PHOTO_FILE)));
}
}
invalidate() not worked. Try hack :
imageView.setImageURI(null);
imageView.setImageURI(newUri);
To force redrawing your widget/View just call View.invalidate();
I had a similar problem where I was using the devices camera to take a picture and then wanting the imageView in the original screen to refresh when I returned to it. The solution was to call View.invalidate() in onResume().
For me, it refreshed my ImageView with this
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PHOTO && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
try {
mProfilePic.setImageURI(null);
mProfilePic.setImageURI(filePath);
Bitmap imageBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
mProfilePic.setImageBitmap(imageBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I would suggest this thing solution. After trying lot of solutions i found this one worked for me.
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 1000ms
ivProfilePic.setImageBitmap(bitImage);
}
}, 1000);
UIView.transition(with: bannerImageView, duration: 0.3, options: [.transitionCrossDissolve], animations: { [weak self] in
self?.exampleImageView.image = newImage
})
Use this func in your view controller
If you are also setting the image using Glide then check if the url is setting up the image or not. If the Glide fails and sets the error Image then setImageURI won't change the image.
This happened in one of my projects. I though this might help someone.