Resolving content uris in android
by Bill Farmer.
Categories:
Hacking
.
If you write an android app that handles images or any other sort of file your app may be required to deal with ‘content’ uris (content://
). There is a very useful utility which resolves these into ‘file’ uris (file:///
) FileUtils.java. This contains one external reference to LocalStorageProvider, which can be resolved by removing the function isLocalStorageDocument()
and references to it.
// import com.ianhanniballake.localstorage.LocalStorageProvider;
// ...
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is {@link LocalStorageProvider}.
* @author paulburke
*/
public static boolean isLocalStorageDocument(Uri uri) {
return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
}
Having done that, you can then resolve ‘content’ uris
public final static String CONTENT = "content";
// ...
if (uri.getScheme().equalsIgnoreCase(CONTENT))
uri = resolveContent(uri);
// ...
// resolveContent
private Uri resolveContent(Uri uri)
{
String path = FileUtils.getPath(this, uri);
if (path != null)
{
File file = new File(path);
if (file.canRead())
uri = Uri.fromFile(file);
}
return uri;
}
This may not always work, but I haven’t been able to defeat it. Later versions of android have added a ‘Documents’ folder, which is encoded as ‘home’, so some additional code is required to resolve it.
/**
* Get a file path from a Uri. This will get the the path for
* Storage Access Framework Documents, as well as the _data field
* for the MediaStore and other file-based ContentProviders.<br>
* <br>
* Callers should check whether the path is local before assuming
* it represents a local file.
*
* @param context The context.
* @param uri The Uri to query.
* @see #isLocal(String)
* @see #getFile(Context, Uri)
* @author paulburke
*/
@TargetApi(19)
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];
}
// /Documents
else if ("home".equalsIgnoreCase(type))
{
return Environment
.getExternalStorageDirectory() + "/Documents/" +
split[1];
}
// TODO handle non-primary volumes
}
// ...
}
// ...
}
See Also
- Flutter app bar search widget
- Android Navigation Menu
- Update App Widget
- Create a Word Grid
- Android Flutter