Android获取文件路径报错"column '_data' does not exist"第三方分享崩溃求助
Hey there! Let's break down why your app is crashing and how to fix it:
What's Going Wrong?
Your current getpath method has two critical issues:
- You're using
MediaStore.Video.Media.DATAto query images—that's a clear mismatch! Even for videos, this field is deprecated starting from Android 10 (API 29) and won't work for URIs that don't come directly from the system media library. - Third-party apps like WhatsApp often use
FileProviderto share files, which generates URIs that don't map to a public, accessible file path. When you try to queryDATAfor these URIs, the cursor will either return null or throw an exception, causing your app to crash.
Solution 1: Read Content Directly (Recommended)
Instead of chasing a file path, use ContentResolver.openInputStream() to read the shared content directly. This works for all valid shared URIs, including those from FileProvider:
public InputStream getSharedContentStream(Context context, Uri contentUri) throws IOException { return context.getContentResolver().openInputStream(contentUri); }
You can use this input stream to copy the file to your app's private storage, process it immediately, or display it—no need for a raw file path at all.
Solution 2: Get a Usable File Path (If You Must)
If you absolutely need a file path (e.g., for legacy code integration), copy the shared content to your app's private directory and use that path. Here's a robust implementation:
public String getUsableFilePath(Context context, Uri uri) { if (uri == null) return null; // Handle content URIs (most common for shared files) if ("content".equalsIgnoreCase(uri.getScheme())) { try (Cursor cursor = context.getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null)) { if (cursor != null && cursor.moveToFirst()) { String fileName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)); File tempFile = new File(context.getFilesDir(), fileName); // Copy the shared content to our private file try (InputStream in = context.getContentResolver().openInputStream(uri); OutputStream out = new FileOutputStream(tempFile)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } return tempFile.getAbsolutePath(); } } } catch (Exception e) { e.printStackTrace(); } } // Handle file URIs (less common now, but still possible) else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; }
Key Notes to Avoid Future Crashes
- Ditch
MediaStore.Xxx.Media.DATA: This field is deprecated and unreliable for shared content. UseOpenableColumnsor direct stream access instead. - Wrap operations in try-catch: Always handle exceptions from cursor and stream operations to prevent unhandled crashes.
- Respect scoped storage: Android 10+ restricts direct access to public storage. Using your app's private directory (via
getFilesDir()) is safe and doesn't require extra permissions.
内容的提问来源于stack exchange,提问作者Drake
相关产品推荐
相关产品推荐

