简体   繁体   English

Android:捕获的图像未显示在图库中(Media Scanner意图不起作用)

[英]Android: captured image not showing up in gallery (Media Scanner intent not working)

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. 我希望这张照片也出现在图片库中,我正在使用Media Scanner意图,但它似乎不起作用。 I was following the official Android developer guide when writing the code, so I don't know what's going wrong. 我在编写代码时遵循官方的Android开发人员指南,所以我不知道出了什么问题。

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: 返回Image Capture意图后运行的代码:

@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. 我也尝试使用Intent.ACTION_MEDIA_MOUNTED而不是Intent.ACTION_MEDIA_SCANNER_SCAN_FILE ,但在这种情况下,我收到了“权限被拒绝”错误。 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. 当我记录传递给intent的URI时,我得到file:///storage/emulated/0/Pictures/JPEG_20150803_104122_-1534770215.jpg ,这应该没问题。 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! 提前致谢!

It depends on how this device Gallery implement. 这取决于这个设备Gallery如何实现。 Popular photo apps receive Intent.ACTION_MEDIA_SCANNER_SCAN_FILE broadcast but some just listen to Android media database. 受欢迎的照片应用程序接收Intent.ACTION_MEDIA_SCANNER_SCAN_FILE广播,但有些只是收听Android媒体数据库。

Alternative you can insert a image into the MediaStore manually at the same time. 另外,您可以同时手动将图像插入MediaStore

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 . 另外,请确保您的照片不在private文件夹中,如内部存储或使用Context.MODE_PRIVATE写入。 Otherwise other apps will not have the permission to access this file. 否则,其他应用程序将无权访问此文件。

In Android if you capture or add images in SD card or Etc. from the application. 在Android中,如果您从应用程序中捕获或添加SD卡或等等中的图像。

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. 你可能不会当场看到。

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 这里imagePath是捕获的图像完整路径

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 . 你只需要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. 从文档中获取的其余代码不需要任何修改,但在原因不同的情况下检查其他答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM