Android Studio 无法使用CameraX将应用程序内拍摄的图像保存到图库,因为“不允许操作”

xfb7svmp  于 2023-01-17  发布在  Android
关注(0)|答案(1)|浏览(385)

我尝试在CameraActivity中拍摄图像并将其保存到图库。我尝试按照网上找到的教程操作,但它不起作用,可能是权限问题?我尝试根据其他stackpverflow帖子修复该问题,但它不起作用:(相机打开,但它不拍摄或保存图像。
这是相机活动的代码:

public class CameraActivity extends AppCompatActivity {

    private int MY_CAMERA_REQUEST_CODE = 100;
    private TextureView view_finder;
    private Button closeCamBtn;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        view_finder = findViewById(R.id.view_finder);

        if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_REQUEST_CODE);
        }
        else{
            startCamera();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_CAMERA_REQUEST_CODE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
            }
        }
    }

    // always end up in onError()
    private void startCamera() {
        CameraX.unbindAll();

        Rational aspectRatio = new Rational(view_finder.getWidth(), view_finder.getHeight());
        Size screen = new Size(view_finder.getWidth(), view_finder.getHeight());

        PreviewConfig pConfig = new PreviewConfig.Builder().setTargetAspectRatio(aspectRatio).setTargetResolution(screen).build();
        Preview preview = new Preview(pConfig);

        preview.setOnPreviewOutputUpdateListener(
                output -> {
                    ViewGroup parent = (ViewGroup) view_finder.getParent();
                    parent.removeView(view_finder);
                    parent.addView(view_finder);

                    view_finder.setSurfaceTexture(output.getSurfaceTexture());
                }
        );

        ImageCaptureConfig imageCaptureConfig = new ImageCaptureConfig.Builder().setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY).
                setTargetRotation(getWindowManager().getDefaultDisplay().getRotation()).build();

        final ImageCapture imgCap = new ImageCapture(imageCaptureConfig);

        findViewById(R.id.imgCapture).setOnClickListener(v -> {
            File file = new File(Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + ".jpg");

            Toast.makeText(getBaseContext(), "File would be: " + Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + ".jpg",Toast.LENGTH_LONG).show();

            imgCap.takePicture(file, new ImageCapture.OnImageSavedListener() {

                @Override
                public void onImageSaved(@NonNull File file) {
                    String msg = "Photo capture succeeded: " + file.getAbsolutePath();
                    Toast.makeText(getBaseContext(), msg,Toast.LENGTH_LONG).show();
                }

                @Override
                public void onError(@NonNull ImageCapture.UseCaseError useCaseError, @NonNull String message, @Nullable Throwable cause) {
                    String msg = "Photo capture failed: " + message;
                    Toast.makeText(getBaseContext(), msg,Toast.LENGTH_LONG).show();
                    if(cause != null){
                        cause.printStackTrace();
                        
                    }
                }
            });
        });
        CameraX.bindToLifecycle(this, preview, imgCap);
    }

这是堆栈跟踪:

StackTrace:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/1673950896355.jpg: open failed: EPERM (Operation not permitted)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:492)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
W/System.err:     at androidx.camera.core.ImageSaver.run(ImageSaver.java:75)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err:     at java.lang.Thread.run(Thread.java:923)
W/System.err: Caused by: android.system.ErrnoException: open failed: EPERM (Operation not permitted)*/
(...)

下面是清单权限:

<uses-feature android:name="android.hardware.camera.any" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
ddhy6vgd

ddhy6vgd1#

java.io.FileNotFoundException:/存储/模拟/0/1673950896355.jpg:打开失败:EPERM(不允许操作)
不要尝试将文件保存在外部存储的根目录中。
将图像文件放入公共DCIM或Pictures目录。例如:

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), System.currentTimeMillis() + ".jpg");

在Android 10设备上,您也需要在运行时请求WRITE_EXTERNAL_STORAGE权限。

相关问题