我正在使用 Android 新照片选择器,我试图获取照片的真实文件位置,但照片选择器给了我以下内容URI content://media/picker/0/com.android.providers.media.photopicker/media/1000000020
我还尝试了以下方法来获取真实的文件位置,但是当我检查文件中的图像时,这似乎也给了我一个不准确的位置。
@Composable
private fun getRealPathFromURI(contentUri: Uri): String {
val projection = arrayOf(MediaStore.Images.Media.DATA)
val context = LocalContext.current
val cursor = context.contentResolver.query(contentUri, projection, null, null, null)
val columnIndex = cursor?.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor?.moveToFirst()
val filePath = cursor?.getString(columnIndex!!)
cursor?.close()
println("filepath $filePath")
return filePath!!
}
Run Code Online (Sandbox Code Playgroud)
/sdcard/.transforms/synthetic/picker/0/com.android.providers.media.photopicker/media/1000000003.jpg
这不可能吗?
Android 11
\n targetApi 30
\n不请求READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE
\n使用SAF api 获取如下 uri:
\n "content://com.android.providers.media.documents/document/document%3"
\n并解析uri 像这样:
public static String getRealPath(uri) {\n String docId = DocumentsContract.getDocumentId(uri);\n String[] split = docId.split(":");\n String type = split[0];\n Uri contentUri;\n switch (type) {\n case "image":\n contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;\n break;\n case "video":\n contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;\n break;\n case "audio":\n contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;\n break;\n default:\n contentUri = MediaStore.Files.getContentUri("external");\n }\n String selection = "_id=?";\n String[] selectionArgs = new String[]{\n split[1]\n };\n\n return getDataColumn(getContext(), contentUri, selection, selectionArgs);\n}\n\npublic …Run Code Online (Sandbox Code Playgroud) 当我们从下载文件夹中选择图像时,找到这样的 URI
内容://com.android.providers.downloads.documents/document/msf%3A27
但是当我们尝试从这个 uri 获取真实路径时,我们将继续获取真实路径。仅 Android 10 版本模拟器和部分 Redmi 手机会出现此问题。我尝试了很多方法和技术,但仍在解决。
我们已经检查了以下 URL,但在我的情况下不起作用:
Android Kotlin:使用从文件选择器中选择的文件名获取 FileNotFoundException?
android-get-real-path-of-a-txt-file-selected-from-the-file-explorer
我的代码是:
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
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];
} …Run Code Online (Sandbox Code Playgroud) 我开始一个ACTION_GET_CONTENT意图来选择 PDF:
override fun routeToFilePicker() {
val intent = Intent()
intent.type = MediaType.PDF.toString()
intent.action = Intent.ACTION_GET_CONTENT
activity.startActivityForResult(
Intent.createChooser(intent, "Select PDF"),
REQUEST_CODE_PDF_PICKER
)
}
Run Code Online (Sandbox Code Playgroud)
然后onActivityResult我尝试从 Uri ( ) 创建 PDF content//:path:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_PDF_PICKER ) {
data?.data?.let { pdfUri: Uri ->
val pdfFile: File = pdfUri.toFile() <-- chrash
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
pdfUri.toFile()导致致命异常:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1003, result=-1, data=Intent …Run Code Online (Sandbox Code Playgroud) 使用ACTION_GET_CONTENTIntent选择图像时,我得到一个无法从中打开文件的 URI。如果我尝试打开文件,如下所示:
InputStream in = new FileInputStream(new File(uri.getPath()));
Run Code Online (Sandbox Code Playgroud)
它给出了以下异常:
03-11 15:14:36.132 20557-20557/my.package W/System.err? java.io.FileNotFoundException: /document/image:9537: open failed: ENOENT (No such file or directory)
03-11 15:14:36.138 20557-20557/my.package W/System.err? at libcore.io.IoBridge.open(IoBridge.java:456)
03-11 15:14:36.138 20557-20557/my.package W/System.err? at java.io.FileInputStream.<init>(FileInputStream.java:76)
Run Code Online (Sandbox Code Playgroud)
/document/image:9537 似乎确实是一条不正确的路径,但我如何获得正确的路径?
我使用这个逻辑打开图像选择器:
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("return-data", false);
startActivityForResult(Intent.createChooser(photoPickerIntent, "Complete action using"), PICK_FROM_FILE);
Run Code Online (Sandbox Code Playgroud)
并在 onActivityResult 中检索 Uri,如下所示:
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
....
Uri uri = data.getData();
Run Code Online (Sandbox Code Playgroud)
我需要让文件进行解码以使其更小。