android 选择文件uri转路径

网上找的方法Android13 14都没问题 Android10不行。
对华为畅享20 nova7 适配。

选择音频文件

    private ActivityResultLauncher<String[]> mFilePicker;
    mFilePicker.launch(new String[]{"audio/*"});  //跳转文件选择器

/回调
    mFilePicker = registerForActivityResult(new ActivityResultContracts.OpenMultipleDocuments(), new ActivityResultCallback<List<Uri>>() {
            @Override
            public void onActivityResult(List<Uri> result) {
                if (result != null && !result.isEmpty()) {
                    // 处理选择的文件

                    if (result.get(0) != null) {
                        String str = new UriToPath().getRealPathFromURI(CleanEventAddCallbackSaveActivity.this, result.get(0));
                        QUtils.out("文件路径" + str);
    

                    }
                } else {
                    // 用户取消了文件选择操作
                }
            }
        });
               

//URI转路径工具类


public class UriToPath {
    public String getRealPathFromURI(Context context, Uri uri) {
        // 检查是否是文档类型的URI

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            return uriToFileApiQ(context, uri);
        } else {
            return getRealPathUri(context, uri);
        }

    }


    public String getRealPathUri(Context context, Uri uri) {
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是外部存储的文档
            if (isExternalStorageDocument(uri)) {
                // 外部存储的直接路径
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // 如果是其他类型的外部存储(例如共享存储),则需要进一步处理
                // ...
            }
            // 如果是下载的文档
            else if (isDownloadDocument(uri)) {
                //DocumentsContract.getDocumentId(uri)返回String路径而不是Long类型数字
//              华为畅享20  华为nova7 等华为手机获取的id是带raw:路径问题处理
                final String id = DocumentsContract.getDocumentId(uri);
                if (!TextUtils.isEmpty(id)) {
                    if (id.startsWith("raw:")) {
                        return id.replaceFirst("raw:", "");
                    }
                    try {
                        final Uri contentUri = ContentUris.withAppendedId(
                                Uri.parse("content://downloads/public_downloads"), ContentUris.parseId(uri));
                        return getDataColumn(context, contentUri, null, null);
                    } catch (NumberFormatException e) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                            uriToFileApiQ(context, uri);
                        }
                    }
                }

            }
            // 如果是媒体文档
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // 如果是普通的文件URI
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            if (isHuaWeiUri(uri)) {
                //对华为手机适配 (未验证)
                String uriPath = uri.getPath();
                //content://com.huawei.hidisk.fileprovider/root/storage/emulated/0/Android/data/com.xxx.xxx/
                if (uriPath != null && uriPath.startsWith("/root")) {
                    return uriPath.replaceAll("/root", "");
                }
            }
            return getDataColumn(context, uri, null, null);
        }
        return null;
    }

    private String getDataColumn(Context context, Uri uri, String selection,
                                 String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int columnIndex = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(columnIndex);
            }
        } catch (Exception e) {

        } finally {
            if (cursor != null)
                cursor.close();
        }

        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    private static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    private static boolean isDownloadDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    public static boolean isHuaWeiUri(Uri uri) {
        return "com.huawei.hidisk.fileprovider".equals(uri.getAuthority());
    }

    /**
     * Android 10 以上适配
     *
     * @param context
     * @param uri
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private String uriToFileApiQ(Context context, Uri uri) {

        File file = null;
        QUtils.out("进入uriToFileApiQ方法");
        QUtils.out("uri.getScheme()" + uri.getScheme());
        //android10以上转换
        if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
            file = new File(uri.getPath());
            QUtils.out("执行了11");
        } else if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
            //把文件复制到沙盒目录
            QUtils.out("执行了22");
            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));

//                makeRootDirectory(context.getExternalCacheDir().getAbsolutePath());
//                File cache =getFilePath(context.getExternalCacheDir().getAbsolutePath(),displayName);
                QUtils.out("22异常" + context.getExternalFilesDir(null));
//                File cache = new File(context.getExternalCacheDir().getAbsolutePath(), displayName);
                File cache = new File(context.getExternalFilesDir(null), displayName);
                try {
                    QUtils.out("22异常1" + displayName);
                    InputStream is = contentResolver.openInputStream(uri);
                    QUtils.out("文件复制到沙盒路径" + cache);
                    FileOutputStream fos = new FileOutputStream(cache);
                    FileUtils.copy(is, fos);
                    file = cache;
                    fos.close();
                    is.close();
                } catch (IOException e) {
                    QUtils.out("文件复制到沙盒路径异常" + e.getMessage());
                    getRealPathUri(context, uri);
                }
            } else {
                QUtils.out("执行了22moveToFirst()");
            }
        }
        return file.getAbsolutePath();
    }

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值