Android Gallery on Android 4.4 KitKat returns different URI for Intent.ACTION_GET_CONTENT
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
On Android 4.4 KitKat, ACTION_GET_CONTENT often returns a different kind of Uri than older gallery code expected. The important change is that KitKat introduced the Storage Access Framework and document-style content:// URIs became much more common, so code that assumes a filesystem path starts breaking.
Why the URI Looks Different on KitKat
Before KitKat, many apps expected media picker results to look like classic MediaStore content URIs or even file paths. On Android 4.4, the picker may return document-provider URIs such as:
- '
content://com.android.providers.media.documents/document/image:12345' - '
content://com.android.externalstorage.documents/document/primary:Pictures/demo.jpg'
That does not mean the URI is wrong. It means the platform is exposing content through document providers instead of promising direct filesystem access.
Do Not Convert Everything to a File Path
The old instinct was to turn the returned Uri into a raw path string and then open the file directly. That approach is fragile on KitKat and becomes even less reliable on newer Android versions.
The safer pattern is to treat the result as a content URI and use ContentResolver.
Then read the result as a stream:
This works regardless of whether the URI points to MediaStore, a documents provider, or another content source.
If You Need Metadata, Query the Resolver
Sometimes you need the display name or MIME type rather than the raw bytes. Query the resolver instead of parsing the URI manually.
This is much more reliable than trying to reconstruct a path from the URI authority and document ID.
Understanding DocumentsContract
On KitKat and later, document URIs can be inspected with DocumentsContract if you really need provider-specific handling.
That can help when you need to recognize a provider authority or branch into special handling. But even then, the best default is still “open through ContentResolver,” not “force a filesystem path.”
ACTION_GET_CONTENT Versus ACTION_OPEN_DOCUMENT
ACTION_GET_CONTENT gives you temporary access to user-selected content. If you need longer-lived access that survives beyond the immediate interaction, ACTION_OPEN_DOCUMENT is often the better API because it works with persistable URI permissions.
That distinction matters because many old gallery examples were really trying to solve a document-access problem, not a one-time content selection problem.
Why Old Path-Based Helpers Fail
Many older Android snippets looked up a _data column from MediaStore and treated it as the image path. That approach becomes unreliable because:
- not every provider exposes a
_datacolumn - the content may not map cleanly to a local file path
- future platform versions increasingly discourage path-based assumptions
If your real goal is to upload, decode, or copy the image, you usually do not need the path at all.
Common Pitfalls
The biggest mistake is assuming a returned KitKat URI must be turned into a filesystem path before use. In many cases, that is unnecessary and brittle.
Another mistake is parsing provider-specific URI strings manually instead of opening the content through ContentResolver.
Developers also confuse temporary access from ACTION_GET_CONTENT with persistable document access. Those are different contracts.
Finally, do not assume code written for the pre-KitKat gallery model still matches the storage model introduced by the Storage Access Framework.
Summary
- KitKat often returns document-style
content://URIs forACTION_GET_CONTENT. - That change is normal and comes from the Storage Access Framework.
- Treat the returned value as a content URI and use
ContentResolver. - Avoid converting the URI into a raw filesystem path unless you have a very specific provider-aware reason.
- If you need long-term access, consider
ACTION_OPEN_DOCUMENTinstead ofACTION_GET_CONTENT.
Related reading
- Android get current Locale, not default
- Android Get Current timestamp?
- Android Get Current timestamp?
- Android getResources().getDrawable() deprecated API 22
- Android getResources.getDrawable deprecated API 22
- Android, getting resource ID from string?
- Android global variable
- Android Go back to previous activity
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.