【问题标题】:Can't save captured image in folder using custom camera in android无法使用android中的自定义相机将捕获的图像保存在文件夹中
【发布时间】:2020-03-11 16:13:38
【问题描述】:

我有一个带有自定义相机的简单应用程序,但是当我拍照时,我无法将捕获的图像保存在模拟器的Downloads文件夹中,而是创建了空白文件夹,我不知道为什么以及我的代码中的错误在哪里。我搜索了答案,但没有找到有用的答案。

你能帮忙吗?

图像阅读器

final ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
            List<Surface> outputSurface = new ArrayList<>();
            outputSurface.add(reader.getSurface());
            outputSurface.add(new Surface(textureView.getSurfaceTexture()));
            final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            builder.addTarget(reader.getSurface());
            builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
            builder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
            final ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader imageReader) {
                    Image mCapturedImage;
                    mCapturedImage = imageReader.acquireLatestImage();
                    mFile = getActivity().getExternalFilesDir(null);
                    ImageSaver saver = new ImageSaver(mCapturedImage,getActivity().getExternalFilesDir(null));
                    mBackgroundHandler.post(saver);
                }

            };
            reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
            final CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    showSnackBar("Image saved", Snackbar.LENGTH_LONG);
                    createCameraPreview();
                }
            };

ImageSaver 类

 private static class ImageSaver implements Runnable {

        private final File mFile;
        private Image mImage;

        ImageSaver(Image image, File file) {
            mImage = image;
            mFile = file;
        }

        @Override
        public void run() {

            if (mImage != null) {
                ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);
                FileOutputStream output = null;
                try {
                    SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
                    String format = s.format(new Date());
                    String fileName = format+".jpg";
                    File file = new File(mFile, "image_" + fileName);
                    output = new FileOutputStream(file);
                    output.write(bytes);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (null != output) {
                        try {
                            output.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

【问题讨论】:

  • 嗯...至少在这个问题中,您没有与Downloads 文件夹相关的任何代码。如果您搜索此页面,则问题中出现“下载”的唯一位置是您的开头段落,而不是代码。您的代码设置为将图像写入getExternalFilesDir(null) 中的文件,这是一个合理的选择。否则,在 Android 9 及更早版本上,您需要改用 Environment.getExteranlStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)。在 Android 10+ 上,您需要切换到使用 MediaStore 作为 ContentProvider

标签: java android image android-camera


【解决方案1】:

您的代码正在做正确的事情,因此将图像文件保存到设备,但它正在将其保存到此处返回的路径的结果中:

mFile = getActivity().getExternalFilesDir(null); 

外部文件目录可能指向 myapp/data/data,这是为您的应用写入外部存储的文件保留的“沙盒”数据区域。这与下载文件夹不同,后者将文件保存到手机上的共享(回复:沙盒之外)数据区域。

如果您想保存到下载,您可能需要将图像写入外部网站,然后将 https:// 路径传递给 ViewIntent,它会在浏览器会话中显示您的图像,并为您提供选项从那里下载图像。

在您的代码中,您有:

mFile = getActivity().getExternalFilesDir(null);

但我没有看到 mFile 在 Image Reader 中的声明位置。在您的其他类中,您将其定义为文件。如果 mFile 是一个文件,那么您可能应该执行以下操作:

String mPath = getActivity().getExternalFilesDir(null);
File mFile = new File(mPath + "/temp.jpg");

// but I don't think you need to create a file, just use the path
ImageSaver saver = new ImageSaver(mCapturedImage,mPath);

【讨论】:

  • 所以如果我在真实设备上尝试它,我应该在哪个文件夹中找到它?
  • String spath = getActivity().getExternalFilesDir();应该告诉您物理设备或模拟器上目录的确切路径。在 8 之前的版本中,它位于 myapp/data/data 下。现在,看起来他们将其存储在 device/data/data/com.myco.myapp/files 下。最好的办法是读取从 getExternalFilesDir() 返回的路径。如果您使用的是 Android Studio,则可以转到 View/ToolWindows/DeviceFileExplorer 查看文件。
  • 感谢您的帮助,但我想将图像保存到画廊,所以我应该在路径中写什么?
  • 如果您将图像文件写入文件文件夹,Android 会搜索所有应用程序文件夹以填充图库。这可能就是你想要做的。它不会出现在下载下,但它应该出现在文件下,如果是图像文件,它应该出现在图库中。
  • 所以我应该这样保留它:String spath = getActivity().getExternalFilesDir(null);?
猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 2012-06-10
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多