Android ACTION_IMAGE_CAPTURE with EXTRA_OUTPUT in internal memory - android

When I'm taking a photo from a camera if I'm calling
File file = new File(getFilesDir().getAbsolutePath() + "/myImage.jpg");
Uri outputFileUri = Uri.fromFile(file);
cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
OK button on camera app is not functioning, simply does nothing (actually won't save it to internal memory I provided I guess and therefore the app itself does nothing).
If I however call
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/myImage.jpg");
Uri outputFileUri = Uri.fromFile(file);
cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
everything is fine and photo is stored on SDCard.
My question is, is there a way to store capture photo in full-resolution without SDCard?

The native camera app cannot save the image in your app's private internal directories as those are only available to your particular app.
Instead you can create a custom camera activity to save images to your internal directories or you need to use the stock camera app with external storage.
Note: if you plan on creating a custom camera activity make sure you target at least 2.3 and up. Anything below that mark is very difficult to work with.

The Camera activity will not be able to save the file into your activity's private files directory, that's why it fails quietly. You can move the image from the external storage into your files dir in onActivityResult.

You need to add permission
cameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
This is possible using the file provider. Please refer sample
public getOutputUri(#NonNull Context pContext) {
String photo = photo.jpeg;//your file name
File photoFile = new File(pContext.getFilesDir(), photo);
Uri lProviderPath = FileProvider.getUriForFile(pContext,
pContext.getApplicationContext()
.getPackageName() + ".provider", photoFile);
return lProviderPath;
}
private void capturePhoto() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, getOutputUri(this));
cameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(cameraIntent, 1);
}
Refer following android document for more details
https://developer.android.com/reference/android/support/v4/content/FileProvider

Related

Android camera intent should not allow to save the image to gallery and store it in specified path

when i use this code ->
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
I am able to save the image to specified path but it is also saving to the gallery. I dont want to save the image to gallery. Please help here.
Thanks in advance for your valuable time.
try this
private void captureCameraImage() {
Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, getFilename());
startActivityForResult(chooserIntent, CAMERA_PHOTO);
}
method to return file name that you can specify whre you want to save
public String getFilename() {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images");
if (!file.exists()) {
file.mkdirs();
}
String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
return uriSting;
}
Capture Image using below Intent -
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
// create a file to save the image
File MyDir = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir");
if (!MyDir.exists()){
MyDir.mkdirs()
}
File fileUri = new File(MyDir.getAbsolutePath() + File.separator + "IMG_"+ timeStamp + ".jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
The gallery app scans the folders for Media contents and populates them in gallery.
If you wish not to display your captured images in gallery follow below methods-
Creating A .Nomedia File
Adding A Dot Prefix
I faced the same problem and implemented several workarounds similar to this one.
I tried also to keep the file hidden adding the . prefix to the filname and to put a .nomedia file (see MediaStore.MEDIA_IGNORE_FILENAME) within the folder where I stored the images but in some cases, calling the camera app via intent as usual
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
Uri fileUri = FileProvider.getUriForFile(getContext(), getString(R.string.file_provider_authority), file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_REQUEST_CODE);
} else {
showToastMessage(getString(R.string.no_camera_activity), Toast.LENGTH_LONG);
}
depending on the device and the camera app, this latter might store the picture also within the gallery (usually saving a file with a timestamp as the filename) even if you are providing an Uri associated to a file you are storing within your application private partition.
So I found that the most reliable way of doing what I needed was to control the camera directly by your own or to adopt cwac-cam2 library provided by CommonsWare within YourActivity in this way (note the commented .updateMediaStore() line)
Uri fileUri = FileProvider.getUriForFile(getContext(), getString(R.string.file_provider_authority), file);
CameraActivity.IntentBuilder builder = new CameraActivity.IntentBuilder(this); // this refers to the activity instance
Intent intent = builder
.skipConfirm()
.facing(Facing.BACK)
.to(fileUri)
//.updateMediaStore() // uncomment only if you want to update MediaStore
.flashMode(FlashMode.AUTO)
.build();
startActivityForResult(intent, CAMERA_REQUEST_CODE);

Images not being saved when picture is taken by camera app that isn't the stock camera

I'm currently trying to save images taken from a phone to its gallery, but the code below only works if I choose the stock camera app when the chooser dialog pops up. Whenever I choose another camera app(e.g., the Google camera), the taken picture doesn't get saved any where.
To make things even stranger, sometimes the picture does show up in its designated directory in the gallery, but after 15 mins or so, the same goes for when I use the stock camera app: the picture will get saved in the default camera shots directory, but takes quite a bit to show up in its designated directory, if it shows up there at all.
// Capturing Camera Image will launch camera app request image capture
void captureImage() {
//file uri to store image.
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
// Request camera app to capture image
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
getActivity().startActivityForResult(captureIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
well ,
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
does not work anymore .
you should do something like this :
call Camera Activity :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
and onActivityResult :
if (data.getData() == null) {
Bitmap bm = (Bitmap)
data.getExtras().get("data");
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss").format(new Date());
File pictureFile = new File(Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
.getAbsolutePath()
+ File.separator + "IMG_" + timeStamp);
try {
FileOutputStream fos = new FileOutputStream(
pictureFile);
bm.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
String filePath = pictureFile.getAbsolutePath();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } else {
Uri imgUri =data.getData());
}
It turns out my code was working after all. The pictures were being saved in the new directory, but the problem was that the gallery wasn't being updated, which explains why the photos would randomly appear in the directory later on. Being new to this, it never occurred to me that I would have to update the gallery. I only came to this realization after using ES File Explorer to look through my files. To fix my problem, I just made a new method in my CameraFragment that would call on the media scanner. I called this method from onActivityResult().
Here's the new method, though there's nothing really "new" about it since I ran into the same code on other SO questions:
protected void mediaScan() {
getActivity().sendBroadcast(
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse(fileUri.toString())));
}
I also don't need to call the package manager and iterate through the apps that could handle the camera intent if I'm not giving the option to use choose a picture from a gallery, so I'm going to remove all that from my question.

How can I edit a photo taken via the camera in my application?

In my application I use the camera to take photos.
I use this code to start the camera Activity:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
File file = new File(directory, timeStamp+".png"); //name
Uri outputFileUri1 = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri1);
startActivityForResult(intent, CAMERA_RESULT);
This code is working, but how can I edit the preview image (crop, rotate,...) before my main Activity gets the data in onActivityResult()?
Or how can I start the photo editor for my image from my application?
You should create a Bitmap object out of your image, then you could manipulate it.
String fooFile = "PATH TO FILE";
Bitmap bmp = BitmapFactory.decodeFile(fooFile);
here is a crop example. for more examples just Google for 'Bitmap manipulation android'

How to set up intent for viewing image that is saved in internal storage with default Android viewer?

What I am trying to do is to download image from web (its in GIF format, if that changes anything) and show it on screen with zoom/pan capability. I've successfully downloaded image into Bitmap instance myBitmap, but ImageView doesnt have zooming feature. So instead I'm willing to present it with default viewer which has zoom/pan features. In order to set up intent I need to provide URI to saved file.
So first I save file into internal storage (also giving access to other apps withe MODE_WORLD_READABLE):
try {
FileOutputStream out = openFileOutput("scrible",
Context.MODE_WORLD_READABLE);
myBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (FileNotFoundException e) {
Log.d(myTag, e.toString());
}
Then I successfully check its really readable:
File myFile = new File(getFilesDir(), "scrible");
if (myFile.canRead()) {
Log.d(myTag, "Its readable");
}
Then I try to set up intent (which gives me error: stopped unexpectedly):
Uri fileUri = Uri.fromFile(myFile);
startActivity(new Intent(Intent.ACTION_VIEW, fileUri));
I've tried to set up intent separately and it doesnt give error antil call to startActivity(intent);
What I am doing wrong?
The following works well for me:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(outputFileName)),"image/jpeg");
startActivity(intent);
The difference that I see is that you do not call the setDataAndType.

How do I get camera intent to save more than one image?

I have a following question. I'm using camera intent that starts from a menu button like this
case R.id.camera:
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getTempFile(this)));
startActivityForResult(intent, TAKE_PHOTO_CODE);
return true;
This is working just fine and it saves original image (original size which I want).
Than I also have the following code
private File getTempFile(LovneDobe lovneDobe) {
final File path = new File( Environment.getExternalStorageDirectory(), lovneDobe.getPackageName() );
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
if(!path.exists()){
path.mkdir();
}
return new File(path, "image.jpg");
}
and this code saves the picture on SDcard and it also puts it into my gallery. But the problem I'm facing is that it saves only one picture. When I take another one it overwrites the previous one.
And now my question is how can I modify this so that it would save every picture I would take?
Thank in advance to anyone who is willing to help.
I'm pretty sure It's because you are explicitly overriding the file. In your method "getTempFile", you always give the same path and name for every time you call the method. Try having a static counter, for example, to know how many pictures you have done, and in the return, put something like
return new File(path, "image"+counter+".jpg");

Categories

Resources