Intent passed on startActivityResult() is null always - android

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.

Related

What is the difference between these two ways of taking photos in Android?

I want to understand what is going on in these two scenarios. I am using code directly from the official docs at http://developer.android.com/training/camera/photobasics.html
Assume that all the necessary read/write permissions are present in the Manifest file.
Scenario 1:
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
This code appears to work for me, but I don't know what it's doing exactly. It basically starts up the camera and lets me take a picture, and then in onActivityResult, I can get the thumbnail this way bu pulling it from the intent.
Scenario 2:
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
static final int REQUEST_TAKE_PHOTO = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
...
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras(); //data is null here!!!
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
This scenario, on the other hand, is supposed to let me get the full file, but it doesn't work and throws an error for me because the Intent variable is null, so I don't have access to anything.
My questions:
When you take a picture using the Android camera, does it typically create two files -- a thumbnail and a full file?
In scenario 1, these file(s) are not being written to internal or external storage, but just the RAM, right? The thumbnail is saved in the Intent, but does this imply that the full file is lost / unattainable?
In scenario 2, the Intent is null because I had used takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); for some reason. How do I know where this file is? Do I even really need mPhotoPath or should I be keeping access to File photoFile, which I've lost by the time I reach the onActivityResult method? What is the proper practice for keeping hold of this file? Making it a member variable?
The image creation function in this example uses getExternalStoragePublicDirectory -- is this different from saving in internal storage? I had assumed there were many ways to save a file: Internal storage, RAM, SD Card, storage device connected to the phone (such as an external HDD), the Cloud, etc. How do I know what is what?
It will either return a thumbnail in the Intent (if you don't specify a filename) or save the file to the filename you specified in the original Intent extras. I don't believe there is a way to do both. If you want to save the full image and then make a thumbnail, you'll have to create the thumbnail yourself. See here for details on the Intent: http://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE
The file is being saved to the photoFile Uri that you specified in the Intent here: takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
You should store the Uri somewhere, probably as a member variable, so you can access it later. That is the Uri that the image will be saved to if a picture is successfully taken.
This is going to be the Android user's default Photos folder in this case. getExternalStoragePublicDirectory will be on whatever media is used for shared data - probably an SD card or internal SD storage.

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

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).

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);
}
}
}

error while decoding image captured with camera

I am launching the camera to capture a picture, which is stored in a new file in a specific folder, in the external storage.
The problem is that when I try to decode the image from the file using BitmapFactory.decodeFile() in my onActivityResult() method, the returned image is null. Is this because the file is not yet complete (i.e. the process of the camera has not finished to save the image)? How can I solve this problem?
Here is the code with which I am launching the camera:
private void launchCamera() {
//create folder
File imagesFolder = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Consts.MEDIA_EXTERNAL_FOLDER);
if(!imagesFolder.exists())
imagesFolder.mkdirs();
String fileName = "pic_"+Consts.CAMERA_DATE_FORMAT.format(new Date());
File image = null;
try {
image = File.createTempFile(fileName, ".jpg", imagesFolder);
} catch(IOException e) {
Log.e(TAG, "Error creating new file.");
}
capturedImageURI = Uri.parse(image.getAbsolutePath());
//launch camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageURI);
startActivityForResult(intent, CAMERA_ACTION);
}
And this is when I get the image in the onActivityResult():
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CAMERA_ACTION:
getContentResolver().notifyChange(capturedImageURI, null);
File f = new File(capturedImageURI.toString());
decodedBitmap = Helper.decodeSampledBitmapFromResource(filePath);
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(decodedBitmap);
break;
}
How can I solve this problem?
File, AFAIK, does not understand file:/// URL formats, which is what you will get from capturedImageURI.toString(). Rather than regenerating the File, use the one you already created.

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.

Categories

Resources