Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A workaround to make this library work for Android 11 or higher #874

Open
Mohaymin opened this issue Mar 20, 2022 · 1 comment
Open

A workaround to make this library work for Android 11 or higher #874

Mohaymin opened this issue Mar 20, 2022 · 1 comment

Comments

@Mohaymin
Copy link

This solution might not be feasible for every use-cases, and migrating to the latest library (see #858) my be the best solution. But I'm sharing my approach anyways.

The problem I faced: My objective was to select a photo from Gallery, load it in the image cropper and finally save the cropped photo. But I encountered exception in Android 11+ devices while loading the image in cropper.

The solution I used: Instead of loading the selected image directly into the cropper, I created a copy of the image file and loaded the copied file into the image-cropper.

I used ActivityResultLauncher to select the image from gallery. I created a util class named MyFileUtils for my own convenience. I'll include the snippets of relevant methods of those classes below it. I created an activity named EditImageActivity where I load the copied file into the image cropper. Here's how I created the ActivityResultLauncher to select image from gallery:

private ActivityResultLauncher<Intent> galleryActivityLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
//         the datatype of result is androidx.activity.result.ActivityResult
            if (result.getResultCode() == Activity.RESULT_OK) {

                Intent data = result.getData();

                if (data == null) {
                    Log.d(TAG, "initializeActivityLaunchers: intent data is null");
                    return;
                }
                Uri selectedImageUri = data.getData();
                if (null != selectedImageUri) {
                    // Get the path from the Uri
                    File copyOfSelectedFile = null;
                    try {
                        InputStream inputStream = getContentResolver().openInputStream(selectedImageUri);
                        copyOfSelectedFile = MyFileUtils.createImageFile(DoubtHistoryActivity.this);
                        MyFileUtils.copyInputStreamToFile(inputStream, copyOfSelectedFile);
                        // refer to the following code snippet for implementation of MyFileUtils' methods
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                        return;
                    }

                    selectedImageUri = Uri.fromFile(copyOfSelectedFile);

                    Intent intent = new Intent(TheCurrentActivity.this, EditImageActivity.class);

                    intent.putExtra("FILE_PATH", selectedImageUri.toString())
                            .putExtra(...);
                    startActivity(intent);
                    finish();
                } else {
                    Log.d(TAG, "initializeActivityLaunchers: selected image uri is null");
                    // maybe the user returned from gallery without choosing any image
                }
            }
        });

The following snippet contains implementation of MyFileUtils.createImageFile(..) and MyFileUtils.copyInputStreamToFile(..):

    public static File createImageFile(Activity associatedActivity) throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "Question_" + timeStamp + "_";
        File storageDir = associatedActivity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        Log.d(TAG, "createImageFile: storageDir: " + storageDir.getAbsolutePath());
        // Save a file: path for use with ACTION_VIEW intents
        File temporaryFile = File.createTempFile(
                imageFileName,  /* prefix */
                ".png",         /* suffix */
//                ".jpg",         /* suffix */
//                ".jpeg",         /* suffix */
                storageDir      /* directory */
        );
        temporaryFile.deleteOnExit();
        return temporaryFile;
    }


    // Copy an InputStream to a File.
    public static void copyInputStreamToFile(InputStream in, File file) {
        OutputStream out = null;

        try {
            out = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Ensure that the InputStreams are closed even if there's an exception.
            try {
                if (out != null) {
                    out.close();
                }

                // If you want to close the "in" InputStream yourself then remove this
                // from here but ensure that you close it yourself eventually.
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Inside the EditImageActivity, I have the path of the copied image file. So I convert the path string to path Uri and load it in the image cropper in the following way:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_image);
        Intent intent = getIntent();
        String sourcePath = intent.getStringExtra("FILE_PATH");
        Uri sourceUri = Uri.parse(sourcePath);
        CropImage.activity(sourceUri)
                .setAllowFlipping(false)
                .start(this);
    }

I went through the following links to come up with this solution:

@texPvtLtd
Copy link

Can you send the complete code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants