I've written code in Android to capture an image and then use that image as follows:
private static Intent i;
final static int cons = 0;
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
public void takePicture()
{
i= new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //Open camera
startActivityForResult(i, cons);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Log.d("Testing if condition", "Test"); //This code does not execute
Bundle ext = data.getExtras();
Log.d("Upload image", ext.toString());
sendForUpload(data); // function to upload file to server
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
This code lets me take a photo and it saves to the SD card. However, I'm not sure if the file is sent to the sendForUpload function where I've handled getting the path and uploading the file. In fact nothing inside the if (resultCode == RESULT_OK) block works. How do I use the image captured from this activity?
Well, you have a few problems.
First, you are calling startActivityForResult(i, cons);. cons is 0. You are trying to compare 0 with CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE. Since CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE is 100, that will not work.
Second, you are calling data.getExtras().toString() (split over two Java statements). I would expect this to return a value like android.os.Bundle#34334143. If that is what you want to upload, fine. I am guessing that you want to upload the image. Since you did not include EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE Intent, you get a Bitmap of the thumbnail image taken by the camera via data.getParcelableExtra("data").
Third, you are making inappropriate assumptions:
This code lets me take a photo and it saves to the SD card.
There is no requirement for the camera app to save the image anywhere, let alone to removable storage. In fact, I would argue that this is a bug in your camera app. That is not surprising, as ACTION_IMAGE_CAPTURE implementations have bugs.
where I've handled getting the path and uploading the file
There is no path. You did not include EXTRA_OUTPUT in your ACTION_IMAGE_CAPTURE Intent, and so all you get back is the thumbnail Bitmap.
I'm using this to put the image in a ImageView:
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
You can use bitmap or uri objects for upload or show your picture..
Hope it helps you.
Related
We have been using a bunch of code that uses the camera with the desired end result, but I want to get to the bottom of this with clean code. I'm simply following the Android docs here verbatim, and getting a rotated thumbnail. Below is the code, please find the working project in this branch of my Bitbucket repository.
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");
ImageView view = (ImageView) findViewById(R.id.imageView);
view.setImageBitmap(imageBitmap);
}
}
I know that this is just the thumbnail. But it seems the thumbnail is completely useless, unless you get the full file and read the exif info from that.
I know that StackOverflow says "get the exif rotation from the full image file and rotate the actual bitmap before recompressing it into another jpg file". But isn't this a little too much unnecessary computation? What good is the thumbnail if it's useless by itself without getting the orientation from the full file?
Am I missing something?
How to Prevent Adobe Creative SDK plugin from saving the edited file automatically in android?
When i try to edit the image, the file is automatically saved to device.
It's not possible to avoid saving the image, but you can set where it is saved using the AdobeImageIntent.Builder()'s .withOutput() method. Example:
Intent imageEditorIntent = new AdobeImageIntent.Builder(this)
.setData(uri) // input image source
.withOutput(Uri.parse("file://" + getFilesDir() + "/my-pic-name.jpg")) // output file destination
.build();
Whether you set the location using .withOutput() or not, you will get back the saved image's Uri in your onActivityResult() method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
/*
`1` being an arbitrary int we used as a requestCode
when starting the `imageEditorIntent`
*/
case 1:
// Do things, for example:
Uri editedImageUri = data.getData();
mEditedImageView.setImageURI(editedImageUri);
break;
}
}
}
If you don't want to store the data long term, you might use that Uri to go back and delete the saved image when you are done with it.
I have this code to take a picture and save the picture in /data/data/..., but after taking the picture I get Image saved to: /media/external/images/media/a_number. I have checked the /data/data/... directory and the picture file is not there.
protected void onCreate(Bundle savedInstanceState) {
context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File fileUri = new File(context.getFilesDir(), "INSTALLATION.jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
//...
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
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();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
}
Third-party camera apps have no rights to write to your portion of internal storage.
You are welcome to try writing a ContentProvider that supports the streaming API and supports writing to your internal storage, then use a content:// Uri for ACTION_IMAGE_CAPTURE. I haven't tried this, so I don't know how well it works, and I suspect many camera apps won't expect a content:// Uri there.
Otherwise, your options are:
Give the third-party camera app a location on external storage, then copy the file yourself to internal storage, or
Do not use ACTION_IMAGE_CAPTURE, but instead use the Camera and/or camera2 APIs to take a picture directly in your app
I am developing an app, where an image taken from the native camera app. is to be shown to the user.
The code I did is:
/* Intent */
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, TAKE_PICTURE);
/* Result */
onActivityResult(int requestCode, int resultCode,
Intent returnIntent) {
if(requestCode == TAKE_PICTURE) {
//picture from Camera
if (resultCode == Activity.RESULT_OK) {
if(returnIntent != null) {
try {
// Get the file path where the image is stored.
// This runs fine on all devices, except Samsung ones.
Uri selectedImage = returnIntent.getData();
if(selectedImage == null) {
if(returnIntent.getExtras() != null &&
returnIntent.getExtras().get(AppConstants.DATA) != null) {
// But, I get the image Bitmap here. Means the image is stored in disk.
Bitmap bmp = (Bitmap) returnIntent.getExtras().get(AppConstants.DATA);
}
}
} catch (Exception e) {
//
}
}
}
}
}
The problem here is, the above code works fine on all devices I tried (HTC's, SE's) but it somehow fails in the Samsung ones. The "Uri selectedImage = returnIntent.getData();" never returns anything. As my entire app is built over this logic of file path storing, I am not able to proceed.
Is there any solution people.
See Specify filename for picture to be taken for code to specify an EXTRA_OUTPUT parameter for the Intent which lets you specify a filename for the picture. Remember the filename when the activity result is called and use that if the intent.getData is NULL
And if you read the other comments in that bug report, you'll realize how many problems that picture taking on Android has.
Your best bet is to generate a file path you want to save the picture to and store it in a member variable. Then, when calling camera activity, put it (as Uri) in the MediaStore.EXTRA_OUTPUT extra.
Be sure to override onSaveInstanceState() and onRestoreInstanceState() and save/restore this path properly. This will make sure you'll still have it if the system decides to restart your activity in the meantime (which is very possible due to orientation changes and/or out of memory conditions).
I've got a problem in saving a picture in a full size after capturing it using ACTION_IMAGE_CAPTURE intent the picture become very small , its resolution is 27X44 I'm using 1.5 android emulator, this is the code and I will appreciate any help:
myImageButton02.setOnClickListener
(
new OnClickListener()
{
#Override
public void onClick(View v)
{
// create camera intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Grant permission to the camera activity to write the photo.
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
//saving if there is EXTRA_OUTPUT
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File
(Environment.getExternalStorageDirectory(), "testExtra" + String.valueOf
(System.currentTimeMillis()) + ".jpg")));
// start the camera intent and return the image
startActivityForResult(intent,1);
}
}
);
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// if Activity was canceled, display a Toast message
if (resultCode == RESULT_CANCELED)
{
Toast toast = Toast.makeText(this,"camera cancelled", 10000);
toast.show();
return;
}
// lets check if we are really dealing with a picture
if (requestCode == 1 && resultCode == RESULT_OK)
{
String timestamp = Long.toString(System.currentTimeMillis());
// get the picture
Bitmap mPicture = (Bitmap) data.getExtras().get("data");
// save image to gallery
MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, timestamp, timestamp);
}
}
}
Look at what you are doing:
you specify a path where your just taken picture is stored with intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File (Environment.getExternalStorageDirectory(), "testExtra" + String.valueOf (System.currentTimeMillis()) + ".jpg")));
when you access the picture you 'drag' the data out of the intent with Bitmap mPicture = (Bitmap) data.getExtras().get("data");
Obviously, you don't access the picture from its file. As far as I know Intents are not designed to carry a large amount of data since they are passed between e.g. Activities. What you should do is open the picture from the file created by the camera intent. Looks like that:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
// Limit the filesize since 5MP pictures will kill you RAM
bitmapOptions.inSampleSize = 6;
imgBitmap = BitmapFactory.decodeFile(pathToPicture, bitmapOptions);
That should do the trick. It used to work for me this way but I am experiencing problems since 2.1 on several devices. Works (still) fine on Nexus One.
Take a look at MediaStore.ACTION_IMAGE_CAPTURE.
Hope this helps.
Regards,
Steff