1

I want to create a file from uri in the ActivityResultCallback in android 11. I use uri.getPath() to convert the incoming uri to a file. but, it won't work in android 11. here is my codes:

       private void launchGallery (){
            Intent intent = new Intent(Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            launcherGallery.launch(intent);
        }
    
        ActivityResultLauncher<Intent> launcherGallery = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK) {
                        Intent data = result.getData();
                        if (data != null) {
                            Uri imageUri = data.getData();
                            // ---> getPath() won't work in android 11 <---
                            File file = new File(imageUri.getPath());
                            // I don't want to display the image in an ImageView. 
                            // I need a file object to pass it to this method to encrypt it
                            encryptImage(file);
                            
                        }
                    }
                });

so, how can I create a file from uri in android 11?

max256
  • 35
  • 3
  • 8
  • If you get an uri for a file in ActivityResultCallback then there is already a file for that uri. Pretty unclear what you want. – blackapps Jan 12 '22 at 20:07
  • `uri.getPath() to convert the incoming uri to a file. ` First: that makes no sense. Second that delivers a string with a useless value. – blackapps Jan 12 '22 at 20:09
  • 1
    `// ---> getPath() won't work in android 11 <---` Nor only for Android 11 you get nonsense but also in all other Android versions. – blackapps Jan 12 '22 at 20:10
  • 1
    "I use uri.getPath() to convert the incoming uri to a file. but, it won't work in android 11" -- that has never been reliable. Use the `Uri` itself, such as by passing it to your chosen image-loading library (Glide, Picasso, etc.) to populate an `ImageView`. – CommonsWare Jan 12 '22 at 20:16
  • I want to pass the file to a method to encrypt the image. I don't want to display it in an ImageView. – max256 Jan 12 '22 at 20:19
  • "I want to pass the file to a method to encrypt the image" -- then use `ContentResolver` and `openInputStream()`, as suggested in [the answer from snachmsm](https://stackoverflow.com/a/70687862/115145). – CommonsWare Jan 12 '22 at 20:42

1 Answers1

5

simply: you can't. if Uri would be always a File then there would be no purpose of both class existance. Uri is a "pointer" to a file, which can be read as InputStream

InputStream inputStream = getContentResolver().openInputStream(uri);

you have to read all these bytes and if you REALLY need a File then store this data in your apps Scoped Storage. if you are shure that this is an image (its declared in calling Intent) then you may try to convert this data to Bitmap.

edit: I see you've added encryptImage(..) method call, so for shure you can read Bitmap "straight from" Uri instead of a File without taking users storage space, even for a while

check out such case: note that when you run a file picker launchGallery() then inside of it you can switch folders. there is a possibility to pick file from e.g. Google Drive, or if you have installed, other web-storages (OneDrive, Dropbox etc.). you will get an Uri as a result, but this isn't a real File on local storage. so you can stream it (as through web/network) for reading entirelly, it isn't ready and available at the moment of result callback call (just after picking and returning to your app)

btw. such possibility isn't limited to Android 11 and above, it was there way earlier. just handle Uri as "pointer", do not assume it is pointing on (local) File. in some cases even if user pick local file you will get an Uri pointing on it through some ContentResolver (so use own for read data), thus this won't be a file path (won't be starting with file://)

snachmsm
  • 17,866
  • 3
  • 32
  • 74