I'm trying to take an image inside CameraActivity and save it to the gallery. I tried following a tutorial I found online but it doesn't work, probably an issue with permissions? I tried to fix that based on other stackpverflow posts but it won't work :( The camera opens, but it doesn't take or save an image.
This is the code for CameraActivity:
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 one rror()
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 one rror(@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);
}
And this is the stack trace:
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)*/
(...)
Here's the manifest permissions:
<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" />
CodePudding user response:
java.io.FileNotFoundException: /storage/emulated/0/1673950896355.jpg: open failed: EPERM (Operation not permitted)
Dont try to save your file in root of external storage.
Put an image file in public DCIM or Pictures directory. Like:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), System.currentTimeMillis() ".jpg");
And on Android 10- devices you need to request WRITE_EXTERNAL_STORAGE permission at runtime too.