Nightpoison
Newbie
testing on Pixel 3a, Android API 29 +
So I'm writing an application that needs to take a picture based on an event, other than a user pressing a camera button. No big deal. I just set the event rather than an onclicklistner, right. Sure. The first problem was most of the information out there revolved around intent and calling the basic camera application. So I had to dig into the camera API's. Camera, Camera2, CameraX. Well I'm now looking at Camera2 and CameraX. CameraX seems a lot simpler.
Anyway moving on. I have pulled two different examples that I'm going to strip down to look at just the capture functionality. Both examples have a preview screen, and a button. I'm going to throw the preview screen out and create a take picture event.
The problem I'm having is one application fails to save the picture while the other application I can't find where the pictures are being saved. I believe there is a permission issue that I'm having trouble with.
BOTH
with both applications I have permissions set in my manifest file.
I also check for permission on both API's for both camera and storage access during onCreate()
CameraX
Here is were things differ. I create the file the image is to be saved in this way.
This is where I believe the root issue is for some reason I think its a permission issue. When ever I check if the directory exists and then create the directory if it doesn't exist, and try's to create the directory it always fails. I always see the Toast message. I took a look at the stacktrace and I see the following errors.
It appears that it can't find the file/directory. Based on passed experience with .csv files, and the reading I should be able to look at the device via the Device File Explorer. However when I open it and look at the /storage/emulated/ folder it just gives me a permission denied message.
This is the case even if I'm running an emulator or the app directly on the device.
Camera2
The application that I'm running the Camera2 API appears to save the image, but I cant find the images. I get the same access issue from the screen shot above, and the images are stored in this location. So I feel like its a permission issue still.
For this application I don't attempt to create any new directories.
The problem with this is, in the final code, I will be creating a new folder for each time the application is run, as each time the app is run will be its own log of files. There will be photos and data files that will need to be organized by instance.
But with that said, even if I port this way of saving data to the device, as it appears to save the images, doesn't fail, I still don't have access to the images.
Any insight?
So I'm writing an application that needs to take a picture based on an event, other than a user pressing a camera button. No big deal. I just set the event rather than an onclicklistner, right. Sure. The first problem was most of the information out there revolved around intent and calling the basic camera application. So I had to dig into the camera API's. Camera, Camera2, CameraX. Well I'm now looking at Camera2 and CameraX. CameraX seems a lot simpler.
Anyway moving on. I have pulled two different examples that I'm going to strip down to look at just the capture functionality. Both examples have a preview screen, and a button. I'm going to throw the preview screen out and create a take picture event.
The problem I'm having is one application fails to save the picture while the other application I can't find where the pictures are being saved. I believe there is a permission issue that I'm having trouble with.
BOTH
with both applications I have permissions set in my manifest file.
Code:
<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"/>
I also check for permission on both API's for both camera and storage access during onCreate()
Java:
if(allPermissionsGranted()){
Toast.makeText(MainActivity.this, "Granted", Toast.LENGTH_SHORT).show();
startCamera(); //start camera if permission has been granted by user
} else{
Toast.makeText(MainActivity.this, "Denied", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
private boolean allPermissionsGranted(){
for(String permission : REQUIRED_PERMISSIONS){
if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
CameraX
Here is were things differ. I create the file the image is to be saved in this way.
Java:
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
File file = new File(getBatchDirectoryName(), mDateFormat.format(new Date())+ ".jpg");
public String getBatchDirectoryName() {
String app_folder_path = "";
app_folder_path = Environment.getExternalStorageDirectory() + "/images";
File dir = new File(app_folder_path);
if (!dir.exists() && !dir.mkdirs()) {
Toast.makeText(MainActivity.this, "Trip", Toast.LENGTH_SHORT).show();
}
return app_folder_path;
This is where I believe the root issue is for some reason I think its a permission issue. When ever I check if the directory exists and then create the directory if it doesn't exist, and try's to create the directory it always fails. I always see the Toast message. I took a look at the stacktrace and I see the following errors.
Code:
W/System.err: androidx.camera.core.ImageCaptureException: Failed to write or close the file
W/System.err: at androidx.camera.core.ImageCapture$3.onError(ImageCapture.java:669)
at androidx.camera.core.ImageSaver.lambda$postError$1$ImageSaver(ImageSaver.java:263)
at androidx.camera.core.-$$Lambda$ImageSaver$eAp-cZyzsEk-LVLazzLE-ezQzwo.run(Unknown Source:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:919)
W/System.err: Caused by: java.io.FileNotFoundException: /storage/emulated/0/images/20200730085024.jpg: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:496)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at androidx.camera.core.ImageSaver.run(ImageSaver.java:97)
... 3 more
W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Linux.open(Native Method)
W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255)
at libcore.io.IoBridge.open(IoBridge.java:482)
... 6 more
D/EGL_emulation: eglMakeCurrent: 0xe09de0c0: ver 3 0 (tinfo 0xe0a8fb90)
W/example.camera: JNI critical lock held for 18.377ms on Thread[15,tid=8749,Runnable,Thread*=0xd531e600,peer=0x13c40348,"Binder:8690_3"]
W/example.camera: JNI critical lock held for 19.631ms on Thread[15,tid=8749,Runnable,Thread*=0xd531e600,peer=0x13c40348,"Binder:8690_3"]
It appears that it can't find the file/directory. Based on passed experience with .csv files, and the reading I should be able to look at the device via the Device File Explorer. However when I open it and look at the /storage/emulated/ folder it just gives me a permission denied message.
This is the case even if I'm running an emulator or the app directly on the device.
Camera2
The application that I'm running the Camera2 API appears to save the image, but I cant find the images. I get the same access issue from the screen shot above, and the images are stored in this location. So I feel like its a permission issue still.
For this application I don't attempt to create any new directories.
Java:
file = new File(Environment.getExternalStorageDirectory()+"/"+UUID.randomUUID().toString()+".jpg");
The problem with this is, in the final code, I will be creating a new folder for each time the application is run, as each time the app is run will be its own log of files. There will be photos and data files that will need to be organized by instance.
But with that said, even if I port this way of saving data to the device, as it appears to save the images, doesn't fail, I still don't have access to the images.
Any insight?