In my application I can take a photo and save it with this code:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageCaptureUri = Uri.fromFile(new File(context.getExternalFilesDir(null),
"tmp_image_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageCaptureUri);
intent.putExtra("return-data", true);
I tried to delete the file from my SD card with this code:
File f = new File(imageCaptureUri.getPath());
if (f.exists() == true)
{
boolean state = f.delete();
Toast.makeText(context, "" + state, Toast.LENGTH_LONG).show();
}
The output of the Toast is true but the file is not deleted on the SD card. I tested this on Android KitKat but it should work on older android versions too. Do you have any ideas why I can't delete the photo?
I used android.permission.WRITE_EXTERNAL_STORAGE in my manifest file.
With some quick searching, i see that occasionally a call to System.gc() is occasionally necessary. Call System.gc() after your f.delete()
KitKat have some changes on how apps can or not access files. Even in the external storage.
Because that's a temp file, I suggest you to relocate it to your own app space like context.getCacheDir instead. That will probably work.
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 have carefully copied the following code snippet from an earlier posting and it works, on the simulator and also on my Nexus 9 device, up to a point !
However, all I get is an empty Recent folder and I never reach the code that writes a file.
What must I change to get a proper document tree ?
private void testDocumentTree() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
}
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
String TAG = "onActivityResult";
if (resultCode == RESULT_OK) {
Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
// List all existing files inside picked directory
for (DocumentFile file : pickedDir.listFiles()) {
Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
}
// Create a new file and write into it
DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
try {
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
out.write("A long time ago...".getBytes());
out.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File Not Found, reason: ", e);
} catch (IOException e) {
Log.d(TAG,"IOException, reason: ", e);
}
}
}
Others mentioned the option on DocumentsUI which the user should manually enable. However there is another option. Add these extras on to your ACTION_OPEN_DOCUMENT, ACTION_GET_CONTENT ,ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE intent. Explore button on Storage settings uses these extras while opening DocumentsUI app. I think the first one is enough to show Internal storage and sdcard. The others are good to have.
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
intent.putExtra("android.content.extra.FANCY", true);
intent.putExtra("android.content.extra.SHOW_FILESIZE", true);
Android 10
I tried on Android 10 emulator and OnePlus 7T, "SHOW_ADVANCED" extra does not do anything. User should manually click to "Show Internal storage" on the three dot menu. SDCards are visible by default.
I had the same problem as you do.
I clicked "Show internal storage" in the overflow menu
After that I was able to see "Internal storage" in the drawer
Not sure if this is what you're asking but in the folder picker, where you're seeing only the recent folder, there's a overflow menu where you can toggle between show/hide SD Card.
For me its working on emulator but not on real Android 5 phone.
I even checked google android Directory Selection sample and it also did not work.
So, its surely a bug whose effect can be seen on some phones.
Report this bug to google and wait till it is fixed. Till then all you can do is to restrict access to memory card in your app, which is what you may not want to do. But I think there is nothing that we can do from our side before google fixes it.
If you get any workaround for this you can tell me too.
I launch default camera using intent and store those camera images in external storage using below path:
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + fileName);
But it does not show in gallery. The issue comes in nexus 4,7 and moto G devices with OS 4.4.2
I try with
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri
.parse("file://" + Environment.getExternalStorageDirectory())));
But It not work
You will have to refresh the media scanner cache, try this:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(yourFile)));
You have to tell the device to scan the new media file. Try with this snippet:
MediaScannerConnection.scanFile(
this, new String[]{file.getAbsolutePath()}, null, null);
I think you'd better make a folder in the camera default folder and put your data in it. Check if a file with the name of ".nomedia" is not in that folder.
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 );
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);
}