Android Camera intent with Uri not saving the images on Camera folder - android

I am using Camera Intent with following code
public void clickPicturesThroughCamera() {
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
initImageUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, RETURN_FROM_CAMERA);
} catch (Exception e) {
showToast(getString(R.string.error_opening_camera));
}
}
public void initImageUri() {
ContentValues cv = new ContentValues();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat,
Locale.ENGLISH);
String name =simpleDateFormat.format(Calendar.getInstance().getTime())
+ "_" + new Random().nextInt(100) + ".jpg";
cv.put(MediaStore.Images.Media.TITLE, name);
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cv);
}
The images captured will be stored on /storage/sdcard0/DCIM/Camera/imagename.jpg. But when I click images through default Camera app it will be stored on storage/extSdCard/DCIM/Camera/imagename.jpg as I have used external sdcard to store the the captured images by default.
So my main requirment is that the app I am developing should store the captured images on the default location i.e. storage/extSdCard/DCIM/Camera/imagename.jpg instead of /storage/sdcard0/DCIM/Camera/imagename.jpg. For that what should I do in the above code, so that it will always save the images on default Camera folder.
Thanks

The path can vary among devices. By using MediaStore.Images.Media.EXTERNAL_CONTENT_URI you are asking the device for the correct path.
http://developer.android.com/reference/android/provider/MediaStore.Images.Media.html

Related

saved video doesn't appear in gallery

I hope someone can help me with this problem.
I have an app which enables the user to take a video (.mp4) or pick existing one. If taking a video, the video is saved to a public directory and I triggered the Android to scan the file to add it to media gallery.
Problem is, taking the video is working fine, I can preview the finished video just fine in my app. But this same video won't appear in media gallery and won't be accessible by other apps -except the FileManager-, even though other .mp4 in the same folder appear in the list just fine.
Further info:
In FileManager app, The not-appearing files have icon video icon while the appearing ones got a thumbnail. I can trigger these not-appearing files to be added to media gallery apps by cut and paste the files in FileManager app (so I believe is not due to files being corrupted).
The scan code works fine for the my code that take images from existing camera app, it just won't work for the video ones...
Is there any need for additional permission for this to work? I've added/asked/request permission for write and read from ext. storage and camera in my manifest and code.
This below is how I take the Video and scan it into gallery :
private void takeVideo() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(ctx.getPackageManager()) != null) {
// Create the file where photo should go
File mediaFile = null;
try {
mediaFile = getOutputMediaFile(ctx, MEDIA_TYPE_VIDEO);
} catch (IOException ex) {
Log.e("FragCamera", "takeVideo() : Error occurred while creating File." + ex);
}
if (mediaFile != null) {
Uri mediaUri = Uri.fromFile(mediaFile);
Log.d("FragCamera", "takeVideo() mediaUri: " + mediaUri);
currMediaUri = mediaUri;
currPhotoPath = mediaFile.getAbsolutePath();
Log.d("FragCamera", "takeVideo() currPhotoPath: " + currPhotoPath);
//make the new file available for other apps
updateMediaGallery(mediaFile);
MediaScannerConnection.scanFile(
ctx,
new String[]{currPhotoPath},
new String[]{"video/mp4"},
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.v("FragCameraScan",
"file " + path + " was scanned seccessfully: " + uri);
}
});
takeVideoIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mediaUri);
this.startActivityForResult(takeVideoIntent, I_REQUEST_VIDEO_CAPTURE);
}
}
}
private void galleryAddPic(String filePath) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(filePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
ctx.sendBroadcast(mediaScanIntent);
}
Logcat value for each Log in the code above :
D/FragCamera: takeVideo() mediaUri: file:///storage/emulated/0/DCIM/Camera/VID_20161207_142021.mp4
D/FragCamera: takeVideo() currPhotoPath: /storage/emulated/0/DCIM/Camera/VID_20161207_142021.mp4
V/FragCameraScan: file /storage/emulated/0/DCIM/Camera/VID_20161207_142021.mp4 was scanned seccessfully: null
try using this function
public Uri addVideo(File videoFile) {
ContentValues values = new ContentValues(3);
values.put(MediaStore.Video.Media.TITLE, "My video title");
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, videoFile.getAbsolutePath());
return getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
}
the 'values' is simply meta data about the video

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.

Android saving image in default folder with default image name

my application is making photos and viewing them in ImageView.
Everything works fine, but images I make in my application are saved in folder DCIM/CAMERA/ with names like "1369434756474" or "1369920366597".
I would like to save images like original camera in default folder DCIM/100MSDCF with default names like "DSC00013" or DSC00233".
I am using Sony Xperia X10Mini but I would like my app worked fine on all devices.
Below is my code of requesting image capture:
if (isImageCatchingIntentAvailable()){
String fileName = "photo.jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
mImageCaptureUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
startActivityForResult(intent, MAKE_PHOTO);
}

Get Path and Filename from Camera intent result

I want to make a picture with the camera intent and save it to the default DCIM folder. Then I want to get the path/filename where the picture is stored.
I am trying it with the following code:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE);
With this code, the camera opens and after I have taken one picture it closes and saves the picture to the default image folder (usually /dcim/camera or sdcard/dcim/camera...)
but how can I get the path and filename of the taken picture now?
I have tried almost everything in onActivityResult
I tried
String result = data.getData();
and
String result = data.getDataString();
and
String result = data.toURI();
and
Uri uri = data.getData();
etc.
I researched the last two days to find a solution for this, there are many articles on the web and on stackoverflow but nothing works.
I don't want a thumbnail, I only want the path (uri?) to the image that the camera has taken.
Thank you for any help
EDIT:
When I try:
path=Environment.DIRECTORY_DCIM + "/test.jpg";
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, TAKE_PICTURE);
it does not store the image as test.jpg but with the normal image name 2011-10-03.....jpg (but that is ok too, i only need the path to the image, it does not matter what the name is).
Best regards
EDIT Again
path=Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
File file = new File(path,"test111111111.jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, TAKE_PICTURE);
When I try this, it stores the image to the right folder and with the given name (e.g. test111111.jpg).
But how can I get the filepath now in onActivityResult?
The picture will be stored twice, first on gallery folder, and after on the file you especified on putExtra(MediaStore.EXTRA_OUTPUT, path) method.
You can obtain the last picture taken doing that:
/**
* Gets the last image id from the media store
* #return
*/
private int getLastImageId(){
final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
if(imageCursor.moveToFirst()){
int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
Log.d(TAG, "getLastImageId::id " + id);
Log.d(TAG, "getLastImageId::path " + fullPath);
imageCursor.close();
return id;
}else{
return 0;
}
}
This sample was based on post: Deleting a gallery image after camera intent photo taken
you can use like this in onActivityResult()
if(requestCode==CAMERA_CAPTURE)
{
Cursor cursor = getContentResolver().query(Media.EXTERNAL_CONTENT_URI, new String[]{Media.DATA, Media.DATE_ADDED, MediaStore.Images.ImageColumns.ORIENTATION}, Media.DATE_ADDED, null, "date_added ASC");
if(cursor != null && cursor.moveToFirst())
{
do
{
String picturePath =cursor.getString(cursor.getColumnIndex(Media.DATA));
Uri selectedImage = Uri.parse(picturePath);
}
while(cursor.moveToNext());
cursor.close();
File out = new File(picturePath);
try
{
mOriginal = decodeFile(out);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mSelected.setImageBitmap(mOriginal);
}
}
When you are starting the ACTION_IMAGE_CAPTURE you can pass an extra MediaStore.EXTRA_OUTPUT as the URI of the file where you want to save the picture.
Here is a simple example:
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, TAKE_PICTURE);
EDIT: I just tried on my device and file.createNewFile() solved the problem for me.

Categories

Resources