Android: captured image not showing up in gallery

2019-07-09 10:56发布

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!

4条回答
做自己的国王
2楼-- · 2019-07-09 11:20

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.

查看更多
smile是对你的礼貌
3楼-- · 2019-07-09 11:26

It depends on how this device Gallery implement. Popular photo apps receive Intent.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.

public final void notifyMediaStoreScanner(final File file) {
        try {
            MediaStore.Images.Media.insertImage(mContext.getContentResolver(),
                    file.getAbsolutePath(), file.getName(), null);
            mContext.sendBroadcast(new Intent(
                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

Addition, make sure your photo not in a private folder, like internal storage or write with Context.MODE_PRIVATE. Otherwise other apps will not have the permission to access this file.

查看更多
干净又极端
4楼-- · 2019-07-09 11:35

Try below Code

private void scanGallery(final Context cntx, String path) {
    try {
        MediaScannerConnection.scanFile(cntx, new String[] { path },null, new MediaScannerConnection.OnScanCompletedListener() {
            public void onScanCompleted(String path, Uri uri) {
            //unimplemeted method
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
}

here imagePath is the captured image full path

查看更多
小情绪 Triste *
5楼-- · 2019-07-09 11:43

In my case, it was silently failing because I had both permissions in the manifest:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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.

查看更多
登录 后发表回答