Android 11 文档选择器隐藏选项或获取选中文件路径问题求助
Android 11 文件选择器「文档」选项问题解决方案
隐藏「文档」选项的实现方案
- 系统原生
ACTION_OPEN_DOCUMENT文件选择器不支持自定义隐藏指定分类入口,无法通过官方参数直接去掉「文档」选项。 - 若必须隐藏该选项,可自行实现自定义文件选择器:仅扫描外部存储中符合业务要求的文档格式文件(pdf、doc、docx、xls、xlsx、txt等),自行渲染选择列表,即可规避系统「文档」入口,同时完整保留文档选取能力。
「文档」选项选取文件后路径获取方案
现有代码中注释了document类型的匹配分支,是导致选中文档类文件时无法获取路径的核心原因,可按以下逻辑修正:
代码修正
首先放开注释的document类型分支,补充对应处理逻辑:
if (isMediaDocument(uri)) { Log.e("URI", "" + uri); final String docId = DocumentsContract.getDocumentId(uri); Log.e("docId", "" + docId); final String[] split = docId.split(":"); final String type = split[0]; Log.e("TYPE", "" + type); 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; } else if ("document".equals(type)) { // 新增document类型处理 contentUri = MediaStore.Files.getContentUri("external"); } selection = "_id=?"; selectionArgs = new String[]{split[1]}; String path = getDataColumn(context, contentUri, selection, selectionArgs); // 若获取路径为空,走流读取/复制到缓存逻辑 if (path == null) { path = copyFileToCacheAndGetPath(context, uri); } return path; } if (isGoogleDriveUri(uri)) { return getDriveFilePath(context, uri); } if (isWhatsAppFile(uri)) { return getFilePathForWhatsApp(context, uri); } if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); }
适配说明
- Android 11引入分区存储限制,部分存放在系统公共文档目录、第三方应用私有目录的文件,无法直接通过MediaStore查询获取真实路径,优先推荐使用ContentResolver直接读取文件流处理业务,无需依赖真实路径:
// 直接读取uri对应文件流,适配全版本系统 InputStream inputStream = context.getContentResolver().openInputStream(uri); - 若业务必须使用真实路径,可通过以下逻辑将文件复制到应用私有缓存目录后获取缓存路径,示例方法如下:
private String copyFileToCacheAndGetPath(Context context, Uri uri) { String fileName = getFileName(context, uri); File cacheFile = new File(context.getCacheDir(), fileName); try (InputStream inputStream = context.getContentResolver().openInputStream(uri); FileOutputStream outputStream = new FileOutputStream(cacheFile)) { byte[] buffer = new byte[4096]; int len; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } return cacheFile.getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); return null; } } private String getFileName(Context context, Uri uri) { String fileName = null; Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null); if (cursor != null && cursor.moveToFirst()) { fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)); cursor.close(); } if (fileName == null) { fileName = String.valueOf(System.currentTimeMillis()); } return fileName; }
内容的提问来源于stack exchange,提问作者Amit Patel
相关产品推荐
相关产品推荐

