Android10 and above uri to file uri to real path

After android10, only need to consider the conversion of the file uri in the sandbox and the shared file (anonymous uri), and the uri obtained through the file selector; other types, either cannot be converted into a File, or cannot be obtained, so there is no need to consider

In fact, after android10, it is impossible to get the absolute path of the external file. The only thing that can be done is to copy the shared file to the sandbox directory, and then perform file operations.

The files in the sandbox (beginning with file) can be directly converted to File for use. If you want to operate a shared file (beginning with content), you need to copy it to the sandbox directory first

Kotlin writing

@RequiresApi(Build.VERSION_CODES.Q)
private fun uriToFileQ(context: Context, uri: Uri): File? =
    if (uri.scheme == ContentResolver.SCHEME_FILE)
        File(requireNotNull(uri.path))
    else if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
        //把文件保存到沙盒
        val contentResolver = context.contentResolver
        val displayName = run {
            val cursor = contentResolver.query(uri, null, null, null, null)
            cursor?.let {
                if(it.moveToFirst())
                it.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
                else null
            }
        }?:"${System.currentTimeMillis()}${Random.nextInt(0, 9999)}.${MimeTypeMap.getSingleton()
            .getExtensionFromMimeType(contentResolver.getType(uri))}"

        val ios = contentResolver.openInputStream(uri)
        if (ios != null) {
            File("${context.externalCacheDir!!.absolutePath}/$displayName")
                .apply {
                    val fos = FileOutputStream(this)
                    FileUtils.copy(ios, fos)
                    fos.close()
                    ios.close()
                }
        } else null
    } else null

 

java writing

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public static File uriToFileApiQ(Uri uri) {
        File file = null;
        //android10以上转换
        if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
            file = new File(uri.getPath());
        } else if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
            //把文件复制到沙盒目录
            ContentResolver contentResolver = context.getContentResolver();
            Cursor cursor = contentResolver.query(uri, null, null, null, null);
            if (cursor.moveToFirst()) {
                String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                try {
                    InputStream is = contentResolver.openInputStream(uri);
                    File cache = new File(context.getExternalCacheDir().getAbsolutePath(), Math.round((Math.random() + 1) * 1000) + displayName);
                    FileOutputStream fos = new FileOutputStream(cache);
                    FileUtils.copy(is, fos);
                    file = cache;
                    fos.close();
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }

 

There are a bunch of conversion methods below android9, find it yourself

 

Guess you like

Origin blog.csdn.net/jingzz1/article/details/106188462