【问题标题】:Saving Camera Photo To Gallery From Fragment using File Provider使用文件提供程序将相机照片从片段保存到图库
【发布时间】:2017-03-24 16:29:13
【问题描述】:

我正在关注 Googles Official 文档,了解如何将使用相机拍摄的照片保存到图库。

他们希望您使用getExternalFilesDir 创建一个文件。

    String mCurrentPhotoPath;
    private File createImageFile() throws IOException {
        // Create an image file name

         String imageFileName = "JPEG_" + UUID.randomUUID();
        File storageDir = getExternalFilesDir(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;
    }

mCurrentPhotoPath 等于/storage/emulated/0/Android/data/com.mycompany.myapp/files/Pictures/JPEG_22fda6f2-dad9-4dd9-b327-c1130c8df0eb187766077.jpg

但在下一部分,最重要的部分,将照片添加到图库

他们说:

如果您将照片保存到由 getExternalFilesDir(),媒体扫描器无法访问文件 因为它们对您的应用来说是私有的。

他们使用的确切方法getExternalFilesDir()。 :-(

所以我也查看了documentation。而且我还不太了解,无法弄清楚我需要使用哪种目录方法。我试过getFilesDir(),但它不喜欢Environment.DIRECTORY_PICTURES

但他们没有提供使用他们的方法保存到画廊的方法。他们的代码 sn-p 不起作用

private void cameraIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(getActivity().getApplicationContext(), "com.mycompany.myapp.fileprovider", photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_CODE_CAPUTURE_IMAGE);
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_CAPUTURE_IMAGE && resultCode == Activity.RESULT_OK) {
                galleryAddPic();

        }
        }

    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);
        this.sendBroadcast(mediaScanIntent);
    }

所以我的应用确实将图片保存到图库。我根本看不到它在哪里保存它。

有人知道我做错了什么吗?

【问题讨论】:

  • “他们使用的确切方法是什么” - 文档中的段落不正确。 getExternalFilesDir() 对于您的应用是唯一的,但对于您的应用来说不是私有的。 “他们的代码 sn-p 不起作用”——尝试 MediaScannerConnection 及其 scanFile() 方法。
  • 我试过了,但照片从未保存到我的相机胶卷中。

标签: java android android-fragments


【解决方案1】:

当您将文件添加到 Android 的文件系统时,这些文件不会被 MedaScanner 自动拾取,而且 Android 仅在重新启动时才会运行完整的媒体扫描。问题是完全扫描需要很长时间。

一种解决方案是使用静态 scanFile() 方法。如果您只需要知道文件何时被添加,您可以使用MediaScannerConnection 的静态方法scanFile()MediaScannerConnection.OnScanCompletedListener。静态方法 scanFile() 的名字很糟糕,因为它实际上需要一个路径数组,因此可以用来一次添加多个文件,而不仅仅是一个,但它仍然可以满足我们的需求。 以下是该方法的使用方法:

MediaScannerConnection.scanFile(
  getApplicationContext(),
  new String[]{file.getAbsolutePath()},
  null,
  new OnScanCompletedListener() {
     @Override
     public void onScanCompleted(String path, Uri uri) {
        Log.v("grokkingandroid",
              "file " + path + " was scanned seccessfully: " + uri);
     }
  });

以下信息是静态scanFile()方法的参数。

  • 上下文 :应用程序上下文
  • paths : 一个字符串数组,包含你要添加的文件的路径
  • mimeTypes : 包含文件的 mime 类型的 String 数组
  • 回调:扫描完成时通知的 MediaScannerConnection.OnScanCompletedListener

OnScanCompletedListener 本身必须实现 onScanCompleted() 方法。此方法获取作为参数传入的 MediaStore.Files 提供程序的文件名和 URI。

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多