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.
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 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
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'd like to take photo and compress its size before saving it to file.
According to what I understand from android developer guide, I can only save the photo to file first and then compress it.
File photoFile = //aquire file path to the saved photo...
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i("addNewActivity","onActivityResult");
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
Bitmap bm = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
//...compress the photo and re-save it again to the file.
}
}
Is it the best practice for this flow? Can't I get in callback the byte[] of the image and manipulate it before it is being saved to file?
I would like to ask a question that relates to the ordering of codes.
I am working on a drawing app of which letting user to select image, and then crop the image so as to fit to a drawing plate. Everything works fine using the below code if do not delete the tempFile shown in the code:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PHOTO_PICKED && resultCode == RESULT_OK)
{
if (data == null)
{
Log.w(TAG, "Null data, but RESULT_OK, from image picker!");
Toast t = Toast.makeText(this, R.string.no_photo_picked, Toast.LENGTH_SHORT);
t.show();
return;
}
if (data != null)
{
File tempFile = getTempFile();
String filePath= Environment.getExternalStorageDirectory() +"/"+TEMP_PHOTO_FILE;
Toast.makeText(this, "path "+filePath, Toast.LENGTH_LONG).show();
doodleView.load_pic(filePath);
// if (tempFile.exists()) tempFile.delete();
}
}
The drawing plate is an extended view named doodleView, and would load the cropped chosen image using doodleView.load_pic(filePath); I would also like to remove the tempFile after it is used as these are redundant. Yet if i add if (tempFile.exists()) tempFile.delete(); the program will crash as the File is deleted before the image file is loaded to the extended view.
If then how could it be rearranged? Or is it possible to execute such delete tempFile on extended View? All the main operations of cropping and placing the tempfile is written in MainActivity.
Thanks in advance for your advice!