I have the following problem: I am working on an app where the user can take a picture (to attach to a post) and the picture is saved to external storage. I want this photo to show up in the pictures gallery as well and I am using a Media Scanner intent for that, but it does not seem to work. I was following the official Android developer guide when writing the code, so I don't know what's going wrong.
Parts of my code:
Intent for capturing an image:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Toast.makeText(getActivity(), ex.getMessage(), Toast.LENGTH_SHORT).show();
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
Creating a file to save the image:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
Displaying the image in the view:
private void setPic() {
// Get the dimensions of the View
int targetW = 60;
int targetH = 100;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
img_added.setImageBitmap(bitmap);
}
Broadcasting a Media Scanner intent to make the image show up in the gallery:
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
}
Code to run after the Image Capture intent returned:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
setPic();
galleryAddPic();
}
}
I have also tried to use Intent.ACTION_MEDIA_MOUNTED
instead of Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
, but in that case I got a "permission denied" error. When I log the URI passed to the intent, I get file:///storage/emulated/0/Pictures/JPEG_20150803_104122_-1534770215.jpg
, which should be fine. Everything else works (capturing the image, saving it to external storage and displaying it in the view) except for this, so I really don't know what's going wrong. Does anyone have any idea? Thanks in advance!
In Android if you capture or add images in SD card or Etc. from the application.
It will not shown sometimes in gallery for some time.
If you capture and just wait for some time till syncing process done you will able to see.
You might not see on the spot.
It depends on how this device
Gallery
implement. Popular photo apps receiveIntent.ACTION_MEDIA_SCANNER_SCAN_FILE
broadcast but some just listen to Android media database.Alternative you can insert a image into the
MediaStore
manually at the same time.Addition, make sure your photo not in a
private
folder, like internal storage or write withContext.MODE_PRIVATE
. Otherwise other apps will not have the permission to access this file.Try below Code
here imagePath is the captured image full path
In my case, it was silently failing because I had both permissions in the manifest:
You only need
WRITE_EXTERNAL_STORAGE
. The rest of the code, taken from the docs, didn't need any modifications, but check the other answers in case the cause is different.