6

I am running to the problem with using Droid X's Files app and Astro file manager to select an image file. This two apps return the selected image with the scheme "file://" while Gallery returns the image with the scheme "content://". How do I convert the first schema to the second. Or how do I decode the image with the second format?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
KITT
  • 230
  • 2
  • 3
  • 15

3 Answers3

5

You probably want to convert content:// to file://

For gallery images, try something like this:

Uri myFileUri;
Cursor cursor = context.getContentResolver().query(uri,new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
if(cursor.moveToFirst())
{
    myFileUri = Uri.parse(cursor.getString(0)).getPath();
}
cursor.close
cjb
  • 74
  • 2
  • Solved it before I read this. But this is what I did. Anyway, I can support Files and Astro return data in format file:// by trimming the "file://" away and pass it to BitmapFactory.decodeFile. Thanks for responding. – KITT Jun 10 '11 at 02:34
  • 1
    `Uri.getPath()` returns a `String`, but otherwise +1 for this, because it works. – intrepidis May 12 '15 at 08:29
4

Here, the problem is that, for all files we can't have a content Uri (content://). Because content uri is for those files which are part of MediaStore. Eg: images, audio & video.

However, for supported files, we can find its absolute path. Like for images as follows-

File myimageFile = new File(path);
Uri content_uri=getImageContentUri(this,myimageFile);

The generic method is as follows.

public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        new String[] { MediaStore.Images.Media._ID },
        MediaStore.Images.Media.DATA + "=? ",
        new String[] { filePath }, null);

if (cursor != null && cursor.moveToFirst()) {
    int id = cursor.getInt(cursor
            .getColumnIndex(MediaStore.MediaColumns._ID));
    Uri baseUri = Uri.parse("content://media/external/images/media");
    return Uri.withAppendedPath(baseUri, "" + id);
} else {
    if (imageFile.exists()) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DATA, filePath);
        return context.getContentResolver().insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    } else {
        return null;
    }
}}
Nizam
  • 5,698
  • 9
  • 45
  • 57
3

Use ContentResolver.openInputStream() or related methods to access the byte stream. You shouldn't generally be worrying about whether it is a file: or content: URI.

http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)

hackbod
  • 90,665
  • 16
  • 140
  • 154
  • 1
    Sometimes you want to able to pass the URI you got from some application to another application. Then conversion is useful, as some applications are picky about what kind of URIs they accept (I learnt this the hard way.) Still looking for solution though... – Juozas Kontvainis Jul 27 '11 at 15:15
  • @hackbod, there's a bug with Uri when you swap out the sdcard for another sdcard. The Uri points to a different picture. – KITT Sep 20 '11 at 05:44
  • 1
    That's not a Uri bug, that is just... well what do you expect? :) If you have a path to a file, and swap the underlying filesystem to something else with different contents, you can't count on that path being meaningful anymore. The only wrinkle here is that URIs for the media content provider are not paths but created with a unique ID for each file it has scanned. When you put in a different SD card, the old database will be dropped and the files re-scanned and assigned new ids, so if you have any URIs from the old card they will either be invalid or randomly ref a file on the new card. – hackbod Sep 21 '11 at 18:08