I am trying to take a picture inside my application and save it to
Android/data/com.androidproject/files/Camera/photo.png
I was using this code
private class ClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getActivity().getExternalFilesDir("Camera"),
"photo.png");
Uri outputFileUri = Uri.fromFile(file);
Log.v("FILE", "" + outputFileUri);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, CALL_BACK);
}
}
and someone suggested that I change the line starting with File file = ... to
File file = new File(getActivity().getFilesDir() + File.separator + "Camera" + File.separator + "photo.png");
file.mkdirs();
Which changes the path directory to what I wanted, however it also prevents the camera from completing the action. Meaning I click my button, the camera loads, I press the blue circle to snap the photo, then when I go to click the checkmark it does nothing. I can reload and retake the photo, or press x and cancel but I cannot select the checkmark.
Any ideas?
edit
After playing with it for a few hours I noticed something. When I go to click the checkmark and complete the photo taking operation there is a photo created in the folder. The checkmark doesn't close out the screen and go back to my activity but it creates a dummy type file. It's size is 0kb and its named "1092-309403.jpeg" not "photo.png". This file is also saved under "InternalStorage/DCIM/Camera". It's never fully saved though as my application never technically finishes the operation. As soon as I press x the picture deletes and its like it never happened. I also tried cleaning my project but that doesn't work.
Camera is a third party application and so it can not access your application's private storage. You have to give path to public storage. More information is here Camera Intent not saving photo
You may have folder named photo.png as leftover from your previous attempts. This prevents Camera app from creating a file with the same name. Check Android/data/com.androidproject/files/Camera/ on the external storage and if there is a folder named photo.png there, delete it.
I've a similar problem too, seems Android doesn't like internal storage... By the way, try with createTempFile():
File dir = new File(getActivity().getFilesDir() + File.separator + "Camera" );
File file = File.createTempFile( "photo.png", ".jpg", dir );
Related
I'm using a simple camera intent following the basic tutorial from Android. In this section it talks about saving the image file to disk. However, I haven't yet configured any of these steps, but after capturing the image and returning to my activity, it's still automatically saving my image to disk in /storage/emaulated/0/DCIM/Camera. This doesn't seem to be what's implied by the tutorial - I don't even have the WRITE_EXTERNAL_STORAGE permission in my manifest so I'm not sure why it's even allowed to write to disk. I don't want the image to automatically save to this directory, but rather to a directory of my choosing. I know how to save the image to a custom directory, but how can I prevent the default behavior of saving the image to the directory above?
When you try to take a phto, actually you are start calling Camera App installed in your device. You didn't set WRITE_EXTERNAL_STORAGE, Oh yes, but the App of Camera is set. And when you try to take a picture but want to store the photo into your file, you could try this:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(AVATAR_FILE_TMP));
intent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
startActivityForResult(intent, TAKING_PICTURE_INDEX);
And filePath is the path of the image file you take by Camera. Taking a photo uses Camera App.
If you use the following code, It will not save the default camera roll.
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, receiptUri);
startActivityForResult(takePictureIntent, 1);
But you need WRITE permission in your manifest.
Here is a method that creates a folder with the name for your app in the "pictures" folder on your SD card. You can change it so that it reflects your needs.
// Create a File for saving an image or video
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyAppDirectory");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyAppDirectory", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
return mediaFile;
}
You can call this method when you need it:
File file = getOutputMediaFile(MEDIA_TYPE_IMAGE);
comment this line if have
MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
I am currently trying to create an app which when taking a picture using the camera, when saving the image, it saves to a specific folder location and if the folder doesn't currently exist on the phone, it creates the folder and saves the file to that location. My code does not currently work, although I have tried. Could you please look at my code and advise me on what I need to do.
Here is the code:
else if(v==camera){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File newDirectory = new File(Environment.getExternalStorageDirectory() + "App_Pictures/");
String filename = new String("image1.jpeg");
File outputFile = new File(newDirectory, filename);
outputFile.mkdirs();
startActivity(intent);
}
It looks like you're trying to get an external app to take a picture for you. If this is the case, you need to use startActivityForResult, not startActivity, because you want to receive the resulting photo. Then you will receive the result in the onActivityResult method of your activity. This process is described in detail here.
If you actually want your own app to take the picture, instead of an external app, you'll need to use a completely different approach. Here is an app that starts recording a video right when it is launched, and saves it to a directory on the SD card, so perhaps it's a useful starting point if you want to do it this way.
i've been trying to create a camera-related app. i know that i could create it programmatically from top, but i would prefer using the one that the phone supports.
what i mean is, rather then creating the camera from 0, i would/could call the camera activity. after all, it provides all the system and gui that i needed.
however, the problem is i wanted the result/image took to be saved in a folder that i created before, rather then saving it in the default camera folder. and also renaming the image took that instant from the default 'image' to names that i preferred.
how do i control that ?
Try this. Here am saving picture to sdcard and also changing its name while saving.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri mUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
"pic"+ String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mUri);
If you look at the Camera applicaton source code, it allows for startActivityForResult(..) that can return the image back to you. This is ideally what you'd like to do.
As a Little hint:
MediaStore
Use below method to take picture, SD_CARD_TEMP_DIR is the path and the image name you want it to store. Hope it help
private void takePicture(){
SD_CARD_TEMP_DIR = Environment.getExternalStorageDirectory() + File.separator + "farmerImage"+CassavaPref.getInstance(this).getImageSuffix()+".jpg";
file =new File(SD_CARD_TEMP_DIR);
Intent takePictureFromCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureFromCameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureFromCameraIntent, 1111);
}
I use the following code to take a picture:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(path + "/" + fileName)));
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
Now when I use this, it does save the picture where I specify above, but it also saves a second copy to the default image folder and adds it to the gallery.
I would simply delete the second file, but it seems it would be a tad dangerous as onActivityResult's intent parameter is always null after taking said picture, so I would have to attempt deleting the most recently saved picture.
Is there any way I can prevent this behavior or correct it by getting the URI of the dupicate picture?
Well I've determined that it is pretty much not possible. I am now using a SurfaceView with my own camera activity.
I am using the Camera Activity to capture the picture. I call it with the MediaStore.EXTRA_OUTPUT extra parameter. The image is correctly saved to provided path, put it is saved also to the gallery folder, so I can view the image in "Gallery" application - can I avoid this?
...
File file = new File(Environment.getExternalStorageDirectory(), "Test.jpg" );
iImageOutputUri = Uri.fromFile( file );
// Start camera intent to capture image
Intent intent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE );
intent.putExtra( MediaStore.EXTRA_OUTPUT, iImageOutputUri );
startActivityForResult( intent, CAPTURE_IMAGE );
...
Thanks
Just replace your code
File file = new File(Environment.getExternalStorageDirectory(), "Test.jpg" );
with following code
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Test.jpg");
Description of getExternalFilesDir() :
Returns the absolute path to the directory on the primary external filesystem (that is somewhere on Environment.getExternalStorageDirectory()) where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
How about saving your images with non-image extension ? Something like michael.photo instead of michael.jpg/png etc.That way Gallery app wont take them in and I have seen many such apps keepsafe for example does this.
I don't believe you can avoid this. The gallery application looks through your SD card for images and displays them automatically.