Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OutputFileResults returned by OnImageSavedCallback has an invalid Uri

I am using CameraX API to take pictures in my android app, save them and then display them from their path. With the previous version alpha-09 I was able to do so with onImageSaved(File file). However with the alpha-10 I have to use onImageSaved(OutputFileResults outputFileResults) and then get the path from the uri retrieved by the outputFileResults. But the Uri I get is always wrong. For instance when my image is saved at: "/external/images/media/1581680878237.jpg" I get the uri's path: "/external/images/media/113758".

Here is my code:

ContentValues contentValues = new ContentValues();
                    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "NEW_IMAGE");
                    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");

                    ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(
                            activity.getContentResolver(),
                            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            contentValues).build();

                    imageCapture.takePicture(outputFileOptions, Runnable::run, new ImageCapture.OnImageSavedCallback() {
                        @Override
                        public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                            Uri uri = outputFileResults.getSavedUri();
                            if(uri != null){
                                System.out.println("URI PATH" + uri.getPath());
                                System.out.println("URI PATH" + uri.toString());
                                activity.runOnUiThread(cameraProvider::unbindAll);
                                galleryAddPic(uri);
                                Bundle params = new Bundle();
                                params.putString("FILE_PATH", uri.getPath());
                                Navigation.findNavController(root).navigate(R.id.navigation_edit_image, params);
                            }
                        }

                        @Override
                        public void onError(@NonNull ImageCaptureException exception) {
                            exception.printStackTrace();
                        }
                    });
like image 884
Paul Souteyrat Avatar asked Feb 14 '20 11:02

Paul Souteyrat


2 Answers

So I finally managed to save the image taken by ImageCapture by using an other method (especially an other ImageCapture.OutputFileOptions.Builde). I didn't use an Uri object to save the image but a File object.

                File mImageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "YOUR_DIRECTORY");
                boolean isDirectoryCreated = mImageDir.exists() || mImageDir.mkdirs();
                if(isDirectoryCreated){
                    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/YOUR_DIRECTORY", "YOUR_IMAGE.jpg");
                    ImageCapture.OutputFileOptions.Builder outputFileOptionsBuilder =
                            new ImageCapture.OutputFileOptions.Builder(file);
                    imageCapture.takePicture(outputFileOptionsBuilder.build(), Runnable::run, new ImageCapture.OnImageSavedCallback() {
                        @Override
                        public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                            Bundle params = new Bundle();
                            params.putString("FILE_PATH", file.getPath());
                            Navigation.findNavController(root).navigate(R.id.navigation_edit_image, params);
                        }

                        @Override
                        public void onError(@NonNull ImageCaptureException exception) {
                            exception.printStackTrace();
                        }
                    });
                }

Be aware that if you use outputFileResults.getSavedUri() with this method you will always have a null uri.

like image 52
Paul Souteyrat Avatar answered Nov 18 '22 03:11

Paul Souteyrat


As of CameraX alpha 10, ImageCapture supports 3 types of save location: File, MediaStore URI and OutputStream, depending on which OutputFileOptions.Builder() is used.

The Uri field in OutputFileResults is only populated if the OutputFileOptions is MediaStore URI type. For File type, the caller should have the save location already, there is no need to return the info; for OutputStream type, the save location is unknown to CameraX. See the JavaDoc:

public Uri getSavedUri ()

Returns the Uri of the saved file.

This field is only returned if the ImageCapture.OutputFileOptions is backed by MediaStore constructed with #Builder(ContentResolver, Uri, ContentValues).

For more info, please checkout the developer doc.

like image 41
Xi 张熹 Avatar answered Nov 18 '22 04:11

Xi 张熹