One feature of my app includes the camera. The user takes a picture and the app displays the image.
I start an intent with ACTION_IMAGE_CAPTURE using StartActivityForResult and capture the response with onActivityResult. Usually I can simply call getData() on the intent I receive in onActivityResult and get the content uri for the MediaProvider.
My problem is the following: One one of my test devices, a Huawei ALE-L21, the intent I get in onActivityResult has no data, but instead, it has a parcellable extra. How could I get the users photo from that? Android Studio doesn't tell me the name of the parcellable extra either
Disclaimer: I call getActivity() because I'm using this code in a fragment
This is what I use to get the camera.
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, getResources().getInteger(R.integer.RQ_PERMISSION_WRITE_EXTERNAL_STORAGE));
}
And here's the code in my onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultIntent) {
super.onActivityResult(requestCode, resultCode, resultIntent);
switch (requestCode) {
case 1: //RQ_ImageCapture
case 2: //RQ_ImageSelected
if (resultIntent != null) {
try {
Uri selectedImage = resultIntent.getData();
if(selectedImage != null) {
Bitmap bitmap =
MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImage);
setImageAsBackground(selectedImage, bitmap);
}
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
Usually I can simply call getData() on the intent I receive in onActivityResult and get the content uri for the MediaProvider.
Your code will fail on many of them, including all recent Nexus devices. ACTION_IMAGE_CAPTURE is not supposed to return a Uri. Quoting the documentation:
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.
Since you are not including EXTRA_OUTPUT, you will get a data extra (getData().getExtra("data")) with a thumbnail image.
the intent I get in onActivityResult has no data, but instead, it has a parcellable extra
Given your ACTION_IMAGE_CAPTURE request, that is what you are supposed to get.
If you want a full-size image, include EXTRA_OUTPUT, perhaps pointing to a FileProvider in your app, such as I demonstrate in this sample app. Then, you know the Uri where the photo should go, because you specified that Uri.
Related
I just started using Android Studio to develop an experimental application. My current problem in trying to get one of my navigation bar tabs set to a camera tab so that when pressed, the camera opens, user takes a picture, then the program does something with that picture. However, when I tried to set the tab as a camera, the program immediately crashes after clicking on the tab. I have this portion of the code currently set as my Main for that specific tab.
case R.id.navigation.dashboard:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
return true;
Should I use a button as an alternative?
EDIT: changed title and some details to the question for more clarification
EDIT2: Got the problem fixed, thanks! The problem for me was actually not checking for app permissions manually via the app info even though I had these permission scripts on the XML file already.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
So I forgot to add a permission popup on my program.
Couple of thing are wrong with this:
Why use tabs for camera if you are just going to use an intent for the camera picture.
The intent should look something like this:
Note: imageUri should be set here to be used later
void takePhoto(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(intent, TAKE_PICTURE);
}
Since starting an activity for result you need to declare a variable TAKE_PICTURE:
private static final int TAKE_PICTURE = 123
Maybe you want to use tab for showing the picture, and that can look like this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PICTURE:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(getContentResolver(), selectedImage);
// show image here in an imageView
} catch (Exception e) {
Log.e("Camera", e.toString());
}
}
}
}
If you don't want to open new Activity you can use CameraX library.
Here you have nice sample how to use it.
I'm trying to allow a user to select an image from their gallery to replace an existing one in my activity (which was programatically added based on DB values). Here's the portion of my code that's causing some issues:
public void requestImage(int imageID){
Intent intent = new Intent();
intent.putExtra("imageID",imageID);
intent.setType("image/*");
Log.v("requestImage",Integer.toString(intent.getIntExtra("imageID",0)));
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
int imageID = data.getIntExtra("imageID",0);
Log.v("onactivityresult",Integer.toString(imageID));
} catch (IOException e) {
e.printStackTrace();
}
}
}
The goal is to get the ID of the image that was selected for this function, which I'm passing in to requestImage, through to onActivityResult. onActivityResult contains the code for setting the image's bitmap based on the image selected by the user (omitted from code sample for conciseness).
Note the two logging statements, which result in:
05-27 15:51:31.756 7769-7769/com.praytoday.app.praytoday V/requestImage: 12
05-27 15:45:55.511 2037-2037/com.praytoday.app.praytoday V/onactivityresult: 0
As you'll notice in the logging statements, the first log is actually getting the int from the intent itself, so I am certain it's being set correctly (and there aren't any type issues here).
It seems to me that data must not be the same intent (please excuse my lack of knowledge on the subject of intents - this is pretty new to me).
Things that I have tried:
Using getIntent() instead of data
Not using the createChooser, and instead just using the plain intent
Looking at every question/answer about this I could find
Any help in determining why this extra value is not in the data argument would be much appreciated! Thanks in advance.
I went ahead and just set a global variable to store which image is currently set for replacement. requestImage sets it to the current image ID, and then onActivityResult uses that variable. Not very elegant, but it works!
I want to display the image when I click on the photo and want to set in my ImageView without user select yes or not....
I had searched for it and I also know it very well that the camera app itself gives you the ability to review/retake the image, and once an image is accepted, the activity displays it. But, I want to do it without review/retake the activity display it.....
I am trying this code fine
Initialise
Uri mImageCaptureUri;
For Click on Button
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
File file = new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mImageCaptureUri = Uri.fromFile(file);
try {
intent.putExtra(MediaStore.AUTHORITY, true);
intent.putExtra("return-data", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap bitmap = null;
mPath = mImageCaptureUri.getPath();
System.out.println("THE PAtH:_" + mPath);
BitmapFactory.Options o2 = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(mPath, o2);
ivSelfie.setImageBitmap(bitmap);
}
When I am Click the Photo Than I am Take this screen to select yes or not......
But My requirement is not select review/retake task and direct set to ImageView on activity display when just click and set.....
Actually it's quite useful to have confirmation of taken picture. But, in case if you really don't want to have it, you have to use SurfaceView inside your app and show camera stream here. There is tones of example how to do it, for example consider to check that one.
Use method setImageURI() it will get the bitmap from the uri and set it for you.
Yes it will set the image weather the user press ok or cancel no matter because your file exists on your given path while launching intent.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_FROM_CAMERA) {
// only one line code
ivSelfie.setImageURI(mImageCaptureUri);
}
}
You cannot avoid that screen. The reason is that when you use new MediaStore.ACTION_IMAGE_CAPTURE you are using a different camera application for clicking image. Showing this screen might be the default functionality of the. This screen will be different in different devices depending upon the camera application.
So to get rid of this the only thing you can do is to implement your custom camera instead of using default camera application.
As per default camera app you can't breach that functionality. Instead of, you can use SurfaceView to capture image inside you application. Please have a look at this answer thread.
May be this link will help you.
Thank you
Use "android.intent.extra.quickCapture" for your picture intent.
// File ImagePickerModule.java#248
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra("android.intent.extra.quickCapture",true);
See https://github.com/react-native-community/react-native-image-picker/issues/647 for details.
If you want to use the built-in camera activity which uses the native Android camera, simply do the following.
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
this.startActivityForResult(camera, PICTURE_RESULT);
You want to get the images back from the nifty camera you displayed -- but how?
If you want to get the image back in its full glory, pass in a uri to the Intent within the EXTRA_OUTPUT extra. If you're fine with a smallish bitmap (and you should be), just call the intent as normal.
Now you have two options, deal with the uri of the image that is returned in the EXTRA_OUTPUT extra, or do the following in your onActivityResult method:
if (requestCode == PICTURE_RESULT) //
if (resultCode == Activity.RESULT_OK) {
// Display image received on the view
Bundle b = data.getExtras(); // Kept as a Bundle to check for other things in my actual code
Bitmap pic = (Bitmap) b.get("data");
if (pic != null) { // Display your image in an ImageView in your layout (if you want to test it)
pictureHolder = (ImageView) this.findViewById(R.id.IMAGE);
pictureHolder.setImageBitmap(pic);
pictureHolder.invalidate();
}
}
else if (resultCode == Activity.RESULT_CANCELED) {...}
}
And there you go!
I launch an activity to capture a picture from camera:
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE, null);
i.putExtra("return-data", true);
startActivityForResult(i, PICK_FROM_CAMERA);
Can you please tell me how to get the URI of the capture picture ?
I'm new to Android, but I believe you have to add some extra information to the Intent.
The ACTION_IMAGE_CAPTURE documentation says:
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.
So, I think you should be able to add in this line:
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File ("MyImageCapture")));
And then you should be able to get it from the URI in the onActivityResult.
But I haven't tested this. Hope I haven't lead you astray.
To get the image that was just taken from the camera you would do the following
// Call to take the picture
startActivityForResult(new Intent("android.media.action.IMAGE_CAPTURE"), PICK_FROM_CAMERA);
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == PICK_FROM_CAMERA)
{
Uri uri = data.getData();
// set the imageview image via uri
_previewImage.setImageURI(uri);
}
}