I am using code from http://developer.android.com/training/camera/photobasics.html
Code:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = FileUtilities.createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Toast.makeText(getActivity(),"Error!",Toast.LENGTH_SHORT).show();
}
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
Bundle extras = data.getExtras(); //error
//code after this doesn't get executed
}
}
I'm trying to get access to the thumbnail and the picture being stored on the device. But for some reason when I try the code, I get a null pointer exception on the data.getExtras(); part.
What am I missing here?
That's one of notorious Android development experience.
Android Intent does not guarantee to give captured image in data.getExtras(), especially user utilize 3rd party camera/imaging app. You can find many trials and suggestions in here and anywhere googled with "android camera intent null".
Some common of them are as below.
data.getExtras().get("data");
data.getExtras() with different key (i.e "photo")
data.getData()
Uri.fromFile(f) for EXTRA_OUTPUT predefined path.
Uri.fromFile(f) with some random filename (datetime format or IMG-xxx) without maintaining EXTRA_OUTPUT definition.
I recommend you to find it using breakpoint which route of the variable that the intent given. It would be good to check all of them in if-else if-else approach.
In addition, check out crash report carefully after releasing the app. You may get the error out of the above trials.
To get the ThumbNail, you don't need to create a file etc. please try this code below.
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
and to get the results.
#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");
imgView.setImageBitmap(imageBitmap);
}
}
imgView is the ImageView you want to set the ThumbNail to.
In case if you want to create a file and then try this, [ which is not needed for a Thumbnail], you may want to try adding the following permission to manifest as you are trying to read and write to storage.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
All the best.
Related
I'm developing an Android App that uses an Intent to open the in-built camera, and take a photo that then should be saved to storage and be sent to a different intent that crops it.
I've run the app a few times but can't see any of the photos being saved anywhere in storage. I started debugging the code and found that it was skipping out on the commands in the OnActivityResult method because the resultCode parameter was always going back as 0.
Out of curiosity I manually changed this to the required value of -1, and the code then skipped out on the next if statement because data.getExtras() (data being the Intent parameter) was returning null, even though I had been adding an extra in the code that triggered the Camera Activity.
I can't quite figure out what's happening here. I'd assume the image is saving somehow because no exception is being thrown, but don't see what might be causing the empty values of resultCode and data.
My code is shown below. If anyone can give me a point in the right direction, that would be a massive help!
Thanks,
Mark
public void onClick(DialogInterface dialogInterface, int i) {
if (optionItems[i].equals(OPTION_CAMERA)) {
//intent to open device camera
Intent cameraIntent =
new Intent(
MediaStore.ACTION_IMAGE_CAPTURE
);
//create 'Spond' folder inside photo directory
//target folder for image to be saved
File imagesFolder =
new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES),
getString(R.string.app_name)
);
//create directory if it doesn't already exist
imagesFolder.mkdirs(); //bool return value not needed
//create file with unique id
File image = createFileAtUniquePath(imagesFolder);
//use authority for AndroidManifest to create permission
//to get uri from temporary file in app
String fileProviderAuthority = getApplicationContext().getPackageName() +
getString(R.string.authorities_fileprovider);
Uri uriSavedImage = FileProvider.getUriForFile(
getApplicationContext(),
fileProviderAuthority,
image
);
//pass URI to intent so it will be available in activity result
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
//grant read/write permissions with file
cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(cameraIntent, REQUEST_CAMERA);
The OnActivityResult code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
if (data.getExtras() != null) {
newAccountPhotoUri = (Uri) data.getExtras().get(MediaStore.EXTRA_OUTPUT);
newAccountPhotoFileName = getFileNameFromURI(newAccountPhotoUri);
if (!newAccountPhotoFileName.equals("")) {
appAccountPhotoChanged = true;
//send image to be cropped
cropImage(newAccountPhotoUri);
}
}
}
//...
}
I am using an implicit Intent to take a picture. I have been following the work outlined in this tutorial. The issue that I am having is that the extra added to the Intent is not being delivered. Here is the code I'm using:
private void dispatchTakePictureIntent(Context context) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile(this.getActivity());
} catch (IOException ex) {
Log.e(TAG, "Error creating file: " + ex.toString());
//TODO: 2017/1/24 - Handle file not created
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Error")
.setMessage(ex.toString());
final AlertDialog dialog = builder.create();
dialog.show();
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(context,
"com.example.myapp",
photoFile);
//THIS EXTRA IS NOT BEING ADDED TO THE INTENT
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
galleryAddPic(context, photoFile.getAbsolutePath());
}
}
}
When the onActivityResult method is fired, the Intent is empty. Here is that code:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
//These extras are empty. I have used the debug tool, and there is nothing in here.
Bundle extras = data.getExtras();
//extras is null
imageBitmap = (Bitmap) extras.get("data");
previewImage.setImageBitmap(imageBitmap);
}
}
Why is the intent empty? What do I need to do to fix this issue?
Why is the intent empty?
Because you asked for it to be empty, by including EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE request. Quoting the 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. 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.
What do I need to do to fix this issue?
Either:
Get rid of EXTRA_OUTPUT (if you want a thumbnail-sized image), or
Stop looking for the "data" extra, and look in the location that you specified in EXTRA_OUTPUT
I'm quite new to android but have been working through the examples on google's site - I'm on this one: http://developer.android.com/training/camera/index.html
This is a "simple" example on using the camera function on android. There is a button that calls up an intent. The intent is displayed below.
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO_B:
File f = null;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
} // switch
startActivityForResult(takePictureIntent, actionCode);
As you can see above, the intent putExtra of key MediaStore.EXTRA_OUTPUT. On android's website: http://developer.android.com/reference/android/provider/MediaStore.html#EXTRA_OUTPUT it says that the MediaStore.EXTRA_OUTPUT has a constant value of "output".
Once the user clicks on a button, the intent is called and the following is an extract of the onActivityResult method given in the code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO_S: {
if (resultCode == RESULT_OK) {
handleSmallCameraPhoto(data);
}
break;
} // ACTION_TAKE_PHOTO_S
A method handleSmallCameraPhoto(data); is then called. Here is the code for handleSmallCameraPhoto.
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(mImageBitmap);
mVideoUri = null;
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.INVISIBLE);
}
Now in the above method, we want to getExtras from the intent - so what was putExtra in under method dispatchTakePictureIntent we are extracting.
We see this line here.
mImageBitmap = (Bitmap) extras.get("data");
Isn't the "data" inside extras.get("data") a key for android to extract the extra data for? From dispatchTakePictureIntent, the key was MediaStore.EXTRA_OUTPUT which had a constant of "output" not "data", how does android know what is associated with "data"?
Ok. I actually found the answer on the android website. The answer is here: http://developer.android.com/training/camera/photobasics.html#TaskPath under the heading "Get the Thumbnail"
This is a special case and android saves thumbnails with the key called "data" in the intent.
The site says: This thumbnail image from "data" might be good for an icon, but not a lot more.
I'm writing an application which have to take a picture and send it to a web service.
There is the code I use to :
i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
outputFileUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/appicture.jpg"));
Log.i("URI", outputFileUri.toString());
i.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(i, cameraData);
The URI looks like :
file:///sdcard/appicture.jpg
But if I put "outputFileUri" var in the i.putExtra, my app just quit.
If not, I can take the picture but I can't get her URI then unable to send it to my webservice.
EDIT 1 :
Error log ( on the activity resylt)
06-26 09:17:46.108: I/Cam error(699): java.lang.NullPointerException
EDIT 2 :
If I remove the "outputFileUri", I correctly got the Image. But, then I'm unable to convert the Bitmap into File to be able to send it.
if(resultCode == RESULT_OK){
Bundle extras = data.getExtras();
_bmp = (Bitmap) extras.get("data");
}
EDIT 3 :
The problem was from
_bmp = (Bitmap) extras.get("data");
And the picture is correctly save in the sd card.
Add WRITE_EXTERNAL_STORAGE permission in Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
EDIT:
if you are passing Image Uri in Intent for Capturing image then get image as in onActiityResult as:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == cameraData) {
File picture = new File(Environment.getExternalStorageDirectory() + "/appicture.jpg");
Uri imguri=Uri.fromFile(picture);
}
super.onActivityResult(requestCode, resultCode, data);
}
and if you want to get image as data in onActiityResult then Launch Camra as:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, cameraData);
in onActivityResult:
onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == cameraData) {
Bundle extras = data.getExtras();
_bmp = (Bitmap) extras.get("data"); //Get data here
}
}
}
If you already added the permissions and the path is correct. Could you please try removing ".jpg" at the end of your path
Please add this in Manifest File
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Happy Coding..
im build some apps that call camera activity..
im just to take picture from my apps and send it to web server..
but i can't get my image path..
im always getting NullException Error when try to get image path..
here's my code when calling camera activity :
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
this.startActivityForResult(camera, PICTURE_RESULT);
and this is code for activity result :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICTURE_RESULT){
if (resultCode == Activity.RESULT_OK) {
takePicture(data);
} else if (resultCode == Activity.RESULT_CANCELED) {
}
}
}
protected void takePicture(Intent data) {
Bundle b = data.getExtras();
pic = (Bitmap) b.get("data");
if (pic != null) {
imagePicture.setImageBitmap(pic);
}
}
is there something wrong with my code?
Thanks
Ok, I see your problem. You're not setting the path to begin with. Please look at this doc.
http://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE
So you see, when you call ACTION_IMAGE_CAPTURE you are not passing it the extra EXTRA_OUTPUT that tells the application where the picture is going to be stored. This EXTRA_OUTPUT is the path to the file.
So right under where you make the intent do this:
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
URI pictureUri = Uri.fromFile(new File(<path to your file>));
camera.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);