getExternalStoragePublicDirectory已废弃,如何读取Downloads下无对应MIME的.gpx文件
问题根因
你调用getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)获取的是应用专属外部存储目录,路径一般为/sdcard/Android/data/[你的应用包名]/files/Download,和系统公共Downloads目录(/sdcard/Download)是完全独立的两个位置。你下载文件时用setDestinationInExternalPublicDir存到了公共Downloads目录,自然在应用专属目录中查不到对应文件。
方案1:仅访问本App下载的GPX文件(最优解,无需额外权限)
直接修改下载逻辑,把文件存储到应用专属Downloads目录即可,后续用你原有查询代码就能正常获取文件:
把下载逻辑中原来的路径配置:
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
替换为:
request.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, filename);
修改后你原有查询代码mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).listFiles()就能正常返回你下载的所有GPX文件。
方案2:需要访问公共Downloads目录下的所有GPX文件
GPX格式实际有官方MIME类型application/gpx+xml,如果适配遇到问题也可以直接按文件名后缀筛选,MediaStore查询代码示例如下:
// 权限配置:Android 9及以下需要在清单中加<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />,Android 10+无需额外读写权限 List<Uri> gpxUriList = new ArrayList<>(); Uri collection = MediaStore.Downloads.EXTERNAL_CONTENT_URI; String[] projection = new String[]{ MediaStore.Downloads._ID, MediaStore.Downloads.DISPLAY_NAME }; // 筛选后缀为.gpx的文件 String selection = MediaStore.Downloads.DISPLAY_NAME + " LIKE ?"; String[] selectionArgs = new String[]{"%.gpx"}; try (Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, null)) { int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID); while (cursor.moveToNext()) { long id = cursor.getLong(idColumn); Uri contentUri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, id); // 拿到的contentUri可直接读写,需要File格式可通过Uri转输入流使用,或拷贝到应用专属目录操作 gpxUriList.add(contentUri); } } catch (Exception e) { e.printStackTrace(); }
注意:非文件管理器类应用不要申请
MANAGE_EXTERNAL_STORAGE权限,否则无法通过Google Play审核。
方案3:让用户手动选择GPX文件
如果仅需要用户选中指定GPX文件操作,用ACTION_OPEN_DOCUMENT实现即可:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); // 指定GPX专属MIME类型自动过滤 intent.setType("application/gpx+xml"); // 如部分机型识别有问题,改为通用类型后续手动过滤 // intent.setType("*/*"); startActivityForResult(intent, REQUEST_CODE_PICK_GPX);
在onActivityResult中接收用户选中的文件Uri即可操作。
内容的提问来源于stack exchange,提问作者allim
相关产品推荐
相关产品推荐

