Ahmed Abd Elhalem Ahmed Abd Elhalem - 1 month ago 31
Android Question

Xamarin: GetRealPathFromURI works for images but not for other files

I have button to attach a file

private void ImgAttach_Click(object sender, EventArgs e)
{
var _Intent = new Intent();
_Intent.SetType("*/*");
_Intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(_Intent, "Select File"), 0);
}


After selecting a file, I can get the real path if it is an image. If it is not an image (PDF, DOCX), it does not work! For example, here is the path returned after selecting an image:

"/storage/0403-0201/Pictures/beach_huts.jpg"


but after selecting a file, this error appears


Android.Database.CursorIndexOutOfBoundsException: Index 0 requested,
with a size of 0


protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);

if (resultCode == Result.Ok)
{
Android.Net.Uri selectedUri = data.Data;
////////////////////////
string s = GetRealPathFromURI(selectedUri);
}
}

private string GetRealPathFromURI(Android.Net.Uri contentURI)
{
Android.Database.ICursor cursor = ContentResolver.Query(contentURI, null, null, null, null);
cursor.MoveToFirst();
string documentId = cursor.GetString(0);
documentId = documentId.Split(':')[1];
cursor.Close();

cursor = ContentResolver.Query(
Android.Provider.MediaStore.Images.Media.ExternalContentUri,
null, Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new[] { documentId }, null);
cursor.MoveToFirst();
string path = cursor.GetString(cursor.GetColumnIndex(Android.Provider.MediaStore.Images.ImageColumns.Data));
cursor.Close();

return path;
}

Answer

Normally you would want to check the mime-type of the item selected, but this is a quick hack of handling items that are not in the media store:

string GetRealPathFromURI(Android.Net.Uri contentURI)
{
    try
    {
        Android.Database.ICursor cursor = ContentResolver.Query(contentURI, null, null, null, null);
        if (cursor != null)
        {
            cursor.MoveToFirst();
            string documentId = cursor.GetString(0);
            documentId = documentId.Split(':')[1];
            cursor.Close();
            cursor = ContentResolver.Query(Android.Provider.MediaStore.Images.Media.ExternalContentUri,
                                           null,
                                           Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " = ? ", new[] { documentId },
                                           null);
            cursor.MoveToFirst();
            string path = cursor.GetString(cursor.GetColumnIndex(Android.Provider.MediaStore.Images.ImageColumns.Data));
            cursor.Close();
            return path;
        }
        return contentURI.Path;
    }
    catch (Android.Database.CursorIndexOutOfBoundsException ex)
    {
        return contentURI.Path;
    }
}
Comments