如何从Android图库获取原始图片/视频文件而非Bitmap对象?
如何从Android图库获取原始图片/视频文件(而非Bitmap)
嘿,我完全懂你的需求——不想把选中的媒体文件解码成Bitmap,只想拿到原始文件本身对吧?那咱们来调整一下原来的方案,还要重点适配新Android版本的存储权限规则哦~
先说说原方案的问题
原来的代码依赖MediaStore.Images.Media.DATA字段获取文件路径,但这个字段在Android 10(API 29)及以上已经被废弃了。而且在Scoped Storage(分区存储)的限制下,直接拿到的路径可能没有访问权限,甚至返回的是虚拟路径,直接操作文件会抛出权限异常。
正确的修改方案:通过ContentResolver操作Uri
系统图库返回的Uri本身就代表了选中的文件,我们可以直接用ContentResolver打开输入流,读取原始文件内容,或者把文件复制到自己应用的私有目录(这样后续操作更方便)。
1. 读取原始文件内容并保存到应用私有目录
这是最稳妥的方式,适配所有Android版本:
Uri selectedFileUri = data.getData(); if (selectedFileUri != null) { try { // 打开文件输入流 InputStream inputStream = getContentResolver().openInputStream(selectedFileUri); if (inputStream == null) { return; } // 创建应用私有目录下的输出文件(避免权限问题) String fileName = "selected_media_" + System.currentTimeMillis(); File outputFile = new File(getFilesDir(), fileName); FileOutputStream outputStream = new FileOutputStream(outputFile); // 复制文件内容 byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } // 关闭流资源 inputStream.close(); outputStream.close(); // 现在outputFile就是原始文件的副本,你可以随意操作它了 // 比如获取文件路径:outputFile.getAbsolutePath() } catch (IOException e) { e.printStackTrace(); // 处理异常,比如提示用户操作失败 } }
2. 直接读取文件内容(无需保存副本)
如果只是需要读取文件内容(比如上传到服务器),可以直接操作InputStream,不用先保存到本地:
Uri selectedFileUri = data.getData(); if (selectedFileUri != null) { try { InputStream inputStream = getContentResolver().openInputStream(selectedFileUri); // 这里可以直接把inputStream传给上传方法,或者读取字节数组 byte[] fileBytes = new byte[inputStream.available()]; inputStream.read(fileBytes); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
3. 获取文件的MIME类型(区分图片/视频)
如果需要判断选中的是图片还是视频,可以用这个方法:
String mimeType = getContentResolver().getType(selectedFileUri); // 比如图片的mimeType是"image/jpeg"、"image/png",视频是"video/mp4"等
权限注意事项
- Android 13及以上:需要在Manifest中声明
READ_MEDIA_IMAGES(图片)或READ_MEDIA_VIDEO(视频)权限,并且动态申请。 - Android 10-12:需要声明
READ_EXTERNAL_STORAGE权限并动态申请。 - 不过通过系统图库选择文件时,系统会临时授予该Uri的访问权限,所以即使没有存储权限,也能通过
ContentResolver读取内容,但如果要保存到外部存储,还是需要对应权限。
这样修改后,你就能避开Bitmap解码,直接拿到原始文件啦~
内容的提问来源于stack exchange,提问作者Omid1989
相关产品推荐
相关产品推荐

