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
Related
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.
I successfully save the pictures from android camera
to using the following root paths
Environment.getExternalStorageDirectory()
and
context.getExternalFilesDir(null)
but I cannot save using the following root path
context.getFilesDir()
Do you know if it is possible to save the pictures taken from android camera to the android internal storage which have context.getFilesDir() as root folder?
I use the following code to start the camera:
Intent takePictureIntent = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PICTURE);
//and this code I used to get the camera output
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
if ((requestCode == REQUEST_TAKE_PICTURE) && (resultCode ==
Activity.RESULT_OK)
) {
Toast.makeText(this, "Can get the image.",
Toast.LENGTH_LONG).show();
//Bitmap photo = (Bitmap) data.getExtras().get("data");
// System.out.println("photo "+photo.getWidth());
// final ImageView imageView = (ImageView) findViewById(R.id.imageView1);
// imageView.setImageBitmap(photo);
} else if ((requestCode == REQUEST_TAKE_PICTURE) && (resultCode == Activity.RESULT_CANCELED)) {
Toast.makeText(this, "Cannot get the image.", Toast.LENGTH_LONG).show();
}
}
You cannot use getFilesDir(), because you are launching a third-party camera app to take the picture, and it cannot write to your app's internal storage.
public void onClick_DisplayGallery(View view) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_IMAGE_GALLERY);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
//Gallery
if (requestCode == REQUEST_IMAGE_GALLERY && resultCode ==
RESULT_OK) {
Uri selectedUri = data.getData();
Bitmap bitmap;
try {
bitmap =
BitmapFactory.decodeStream
(getContentResolver().openInputStream(selectedUri));
//places selected images into bitmap for database use
originalBitmapImage = bitmap;
//Process data after image chosen (add image to database)
process_chosenImage();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
} catch (Exception ex) { /
Toast.makeText(MainActivity.this, "Gallery not responding",
Toast.LENGTH_SHORT).show();
//Reset view
resetView_afterImageChosen();
}
When I select images from other galleries besides Camera Directory
and Download Directory, I can save the images to my database with no
problems. Also, when I run my program in the emulator, everything runs
smoothly. However, when it comes to actual devices, my app crashes. I
use Dell Venue 8 to test on actual device, but cannot connect it to the
computer in order to debug it.
How can I save an image to my database from the Camera Directory after
accessing it from the Gallery? I can save images from other directories,
except as I mentioned before, I cannot save images from the Camera
directory and the Downloads directory.
I'm trying to save a photo to external storage and display it in a ImageView, but I don't want other apps can access this photo. I try to create a new File with the method getFilesDir() as the directory argument when I want to create that file, but if I ask if I can write to it (to save the image), it return that I can't (see the code for more details).
Note that the app has the android.permission.WRITE_EXTERNAL_STORAGE permission.
public void takePhoto(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getFilesDir(), "my_image.jpg");
// Check if I can write in this path (I always get that I can't)
if (file.canWrite()) {
Toast.makeText(this, "I can write!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "I CAN'T WRITE!", Toast.LENGTH_LONG).show();
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, IMAGE_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == IMAGE_REQUEST_CODE) {
File file = new File(getFilesDir(), "my_image.jpg");
Bitmap bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
imageView.setImageBitmap(bitmap);
}
}
However, if I use the Environment.getExternalStorageDirectory() method, I'm able to save the photo.
I think I might be misunderstanding anything about how File works, but I don't know exactly what. I have no FC, the image just doesn't show in the ImageView.
If you save to an external storage everyone will see the image :
Here's External Storage!
Then when you receive the callback onActivityResult you will receive the URI from the image
Uri mUriFile = data.getData()
Then depending on the OS version you can get the file path
HereĀ“s a good post to get it Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT
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