在 android 11 中从 uri 创建文件 - getPath() 不起作用

max*_*256 1 android uri file android-11 registerforactivityresult

我想在 android 11 的 ActivityResultCallback 中从 uri 创建一个文件。我用它uri.getPath()来将传入的 uri 转换为文件。但是,它在 android 11 中不起作用。这是我的代码:

       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);
                            
                        }
                    }
                });
Run Code Online (Sandbox Code Playgroud)

那么,如何在 android 11 中从 uri 创建文件?

sna*_*msm 5

很简单:你不能。如果Uri总是 aFile那么两个类的存在就没有目的了。Uri是一个指向文件的“指针”,可以读作InputStream

InputStream inputStream = getContentResolver().openInputStream(uri);
Run Code Online (Sandbox Code Playgroud)

您必须读取所有这些字节,如果您确实需要,File请将这些数据存储在您的应用程序范围存储中。如果您确定这是一个图像(在调用中声明Intent),那么您可以尝试将此数据转换为Bitmap.

编辑:我看到您已经添加了encryptImage(..)方法调用,因此您可以放心地读取Bitmap“直接来自”Uri而不是File不占用用户存储空间,即使是一段时间

查看这种情况:请注意,当您运行文件选择器时launchGallery(),您可以在其中切换文件夹。可以从 Google Drive 等中选择文件,或者如果您已安装,则可以从其他网络存储(OneDrive、Dropbox 等)中选择文件。您将得到一个Uri结果,但这不是真正的File本地存储。因此您可以流式传输它(如通过网络/网络)以完全阅读,它在回调调用时尚未准备好且可用result(在选择并返回到您的应用程序之后)

顺便提一句。这种可能性不仅限于 Android 11 及更高版本,它很早就存在了。只是处理Uri为“指针”,不要假设它指向 (local) File。在某些情况下,即使用户选择本地文件,您也会Uri通过某些文件获得指向它的指向ContentResolver(因此使用 own 来读取数据),因此这不会是文件路径(不会以 开头file://