Failure delivering intent result back to activity, android image capture intent - android

I am trying to implement a simple image capture into my android app, and to return the path where the image was saved. I was following the sample from the android docs, but as I capture an image and press SAVE, my app crashes with the following exception:
Failure delivering result ResultInfo{who=null, request=100, result=-1,
data=null} to activity {com.fideli/com.fideli.MainActivity}:
java.lang.NullPointerException
Why is data=null ?? I was trying to search for a fix but none of them helped. Could someone please help me out with a suggestion?
Thanks!
MainActivity :
private void takePicture() {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//Bundle bundle = data.getExtras();
//Log.i("TAG", "Image saved to:\n" + bundle);
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
// Toast.makeText(this, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
Log.i("TAG", "Image saved to:\n" + data.getData());
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}

The image is written to the Uri that you pass in the Intent extra MediaStore.ACTION_IMAGE_CAPTURE.EXTRA_OUTPUT. The Intent that is passed back to your activity in onActivityResult() doesn't contain the image, nor does it contain the Uri in the data field of the Intent. In onActivityResult() you can get the image from the file that you returned in the call to getOutputMediaFileUri(int type).

Related

Image file missing exif data

Using intent to take a photo, which is later uploaded to a server.
Image is first saved to sdcard like so:
/**
* Creating file uri to store image/video
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image / video
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Config.IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "Oops! Failed create "
+ Config.IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
The saved image has no exif data. Is it due to the uri? (photos taken with the default camera app has exif data so it has to be an issue in my app).
Edit: Code used to launch default camera app:
/**
* Launching camera app to capture image
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
url stored:
/**
* Here we store the file url as it will be null after returning from camera
* app
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on screen orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
Source: http://www.androidhive.info/2014/12/android-uploading-camera-image-video-to-server-with-progress-bar/
photos taken with the default camera app has exif data so it has to be an issue in my app
Not necessarily. From the code that you have shown, it would appear to be a bug in that particular camera app. Not all camera app developers test ACTION_IMAGE_CAPTURE very well. Unless you are modifying the image sometime after the picture is taken but before you run your EXIF test, the camera app is not adding EXIF tags to pictures taken via ACTION_IMAGE_CAPTURE. These things happen.
You might install some camera apps and see how they behave with ACTION_IMAGE_CAPTURE. Open Camera, for example, supports ACTION_IMAGE_CAPTURE, though I have not tested its EXIF behavior when started with ACTION_IMAGE_CAPTURE.

I get null data on onActivityResult

I got this code (from android web) that stores make a file location to store the image once started the activity
{
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */ private static
Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */ private static
File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
then i start my activity like this:
cameraButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
});
and then when i get the result on:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { ... }
i saw that debugging it, "data" is null..
I did the same thing but without adding the
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
and when i add no extra i recieve data info..
guess i have something wrong on writing/reading?? but how? i copyed from the android web!!
I do have permision camera writing reading external storage!
Help!!!!!!!!!!!!!!!
When you specify MediaStore.EXTRA_OUTPUT flag for your intent, the taken picture will be stored in your phone storage and no data will be returned.
from Docs:
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. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.
When you use the approach to store taken picture, you have to pass URI together with the intent to tell where to store taken picture
NightCrawler Gave a link on how to get data back onActivityResult
Copying the most important portion:
YourActivity extends Activity{
onCreate{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
onActivityResult(parameters..) {
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
yourImageView.setImageBitmap(photo);
}
}
}

Warning : Camera failed

I use the following code to call existed camera :
// New intent to Camera feature
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri fileUri = Uri.fromFile((new File((new Date()).toString()))); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
I can capture photo, but can not record the video, I received the error Warning : Camera failed
I try to do something related to some solutions but can not receive good result. (Although reset the phone)
Please tell me how to fix this,
Thanks,
P/s : Device - Samsung Galaxy Tab 7 2.2.1
EDIT :
I use the following code to receive the response, and response the result resultCode == RESULT_CANCELED
if (resultCode == RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Video saved to:\n" +
data.getData(), Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
Toast.makeText(this, "User cancelled the video capture", Toast.LENGTH_SHORT).show();
} else {
// Video capture failed, advise user
Toast.makeText(this, "Warning : Camera failed", Toast.LENGTH_SHORT).show();
}
I compared your code with Android Guide. The only difference is the file uri. You can try the Google's sample code to get the file uri:
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}

Unable to save a photo captured with the native camera app

I'm trying to use the built-in camera app, calling it via an intent from my own app, to take a picture at a specified place. I've use lot of sample code from developer.android.com but it throws an exception:
java.lang.RuntimException: Failure delivering result ResultInfro(who=null, request=1, result=1, data=null).
I check the SDcard but no image is created. I've read lot of threads here, but none of them helped me.
My code:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()) {
if (! mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
Uri fileUri = Uri.fromFile(getOutputMediaFile());
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, TAKE_PICTURE);
And what I do next:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
//taken photo
case TAKE_PICTURE:
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
This answers a very similar question:
I'm getting a NullPointerException when I use ACTION_IMAGE_CAPTURE to take a picture
Simplest solution is to keep an instance variable with the file name at the time when you start the activity, and load the file name from that instance variable during onActivityResult.

Intent passed on startActivityResult() is null always

In my app, I have to capture a photo from the native camera app and then store it in my desired folder and then show that captured image in a new Activity. My code so far
To start native camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
My other methods
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/**Create a file for saving an image*/
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "KidzPuzzle");
//Create a storage directory if it does not exist
if(! mediaStorageDir.exists()){
if(! mediaStorageDir.mkdirs()){
Log.d("KidzPuzzle", "Failed to create directory");
return null;
}
}
//Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = null;
if(type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath()+File.separator+"IMG_"+timeStamp+".jpg" );
return mediaFile;
}else{
return null;
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){
if(resultCode == RESULT_OK){
//Image created and saved successfully to the specified fileUri
//Toast.makeText(this, "Image saved to : \n"+data.getDataString(), Toast.LENGTH_LONG).show();
String filePath = ((Uri) data.getExtras().get(MediaStore.EXTRA_OUTPUT)).toString();
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
startActivity(new Intent(this, SplitImageActivity.class).putExtra("image", bitmap));
}else if(resultCode == RESULT_CANCELED){
//user canceled the captured image
}else{
//Image capture failed
}
}
}
The intent variable data in onActivityResult is always null. Please help me where I am going wrong.
NOTE: When I debug it, the control always satisfies the RESULT_OK condition and the shows NullPointerException, because of the value of data.
And another thing, if I am not using
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
this code before starting the native camera, then data is not null.
please help me.
Chandra Sekhar,
as you have mentioned in the last that when you don't specify location for the image then data is not null so AFAIK it clearly indicates that when you pass location then it will return null and you will receive your image at your location. So you need to store that location separately and use that to access image when you get RESULT_OK.

Categories

Resources