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.
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);
}
For Samsung devices add below one line in your AndroidManifest.xml File
android:configChanges="orientation|screenSize"
i hope this will work for you
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!
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);
}
}
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);
}
}