如何从Uri Xamarin Android获取实际路径 [英] How to get actual path from Uri xamarin android

查看:80
本文介绍了如何从Uri Xamarin Android获取实际路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Uri获取实际路径,当我使用Intent选择文件时,它将返回URI,但在下面的代码行下无法将URI转换为字符串路径

I want to get actual path from Uri, when I select file using intent then it will be returning URI but below line of code not working for conversion URI to string path

打开FilePicker

public static void PickFile(Activity context)
{
    Intent intent = new Intent(Intent.ActionGetContent);
    intent.SetType("*/*");
    context.StartActivityForResult(intent, PICKFILE_RESULT_CODE);
}

获得结果

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    if(requestCode == PICKFILE_RESULT_CODE)
    {
        string filepath = GetRealPathFromURI(MainActivity.act, data.Data);
    } 
}

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

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

        return path;
    }
    catch(Exception e)
    {
        Log.Debug("TAG_DATA",e.ToString());
        return "";
    }
}

错误

System.IndexOutOfRangeException:索引超出了 数组.

System.IndexOutOfRangeException: Index was outside the bounds of the array.

任何人都可以向我解释,认为我在这段代码中做错了什么.

can anyone explain to me, what's wrong think I am doing in this code.

推荐答案

如何从Uri xamarin android获取实际路径

How to get actual path from Uri xamarin android

我注意到您正在使用MediaStore.Images.Media.ExternalContentUri属性,您要获取的是Gallery Image的真实路径吗?

I note that you are using MediaStore.Images.Media.ExternalContentUri property, what you want is getting the real path of Gallery Image?

如果要实现此功能,可以阅读我的回答:获取图库图像的路径?

If you want implement this feature, you could read my answer : Get Path of Gallery Image ?

private string GetRealPathFromURI(Android.Net.Uri uri)
{
    string doc_id = "";
    using (var c1 = ContentResolver.Query(uri, null, null, null, null))
    {
        c1.MoveToFirst();
        string document_id = c1.GetString(0);
        doc_id = document_id.Substring(document_id.LastIndexOf(":") + 1);
    }

    string path = null;

    // The projection contains the columns we want to return in our query.
    string selection = Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " =? ";
    using (var cursor = ContentResolver.Query(Android.Provider.MediaStore.Images.Media.ExternalContentUri, null, selection, new string[] { doc_id }, null))
    {
        if (cursor == null) return path;
        var columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
        cursor.MoveToFirst();
        path = cursor.GetString(columnIndex);
    }
    return path;
}

更新:

这是一个解决方案:

private string GetActualPathFromFile(Android.Net.Uri uri)
{
    bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;

    if (isKitKat && DocumentsContract.IsDocumentUri(this, uri))
    {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri))
        {
            string docId = DocumentsContract.GetDocumentId(uri);

            char[] chars = { ':' };
            string[] split = docId.Split(chars);
            string type = split[0];

            if ("primary".Equals(type, StringComparison.OrdinalIgnoreCase))
            {
                return Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
            }
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri))
        {
            string id = DocumentsContract.GetDocumentId(uri);

            Android.Net.Uri contentUri = ContentUris.WithAppendedId(
                            Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));

            //System.Diagnostics.Debug.WriteLine(contentUri.ToString());

            return getDataColumn(this, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri))
        {
            String docId = DocumentsContract.GetDocumentId(uri);

            char[] chars = { ':' };
            String[] split = docId.Split(chars);

            String type = split[0];

            Android.Net.Uri contentUri = null;
            if ("image".Equals(type))
            {
                contentUri = MediaStore.Images.Media.ExternalContentUri;
            }
            else if ("video".Equals(type))
            {
                contentUri = MediaStore.Video.Media.ExternalContentUri;
            }
            else if ("audio".Equals(type))
            {
                contentUri = MediaStore.Audio.Media.ExternalContentUri;
            }

            String selection = "_id=?";
            String[] selectionArgs = new String[] 
            {
                split[1]
            };

            return getDataColumn(this, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
    {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.LastPathSegment;

        return getDataColumn(this, uri, null, null);
    }
    // File
    else if ("file".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
    {
        return uri.Path;
    }

    return null;
}

public static String getDataColumn(Context context, Android.Net.Uri uri, String selection, String[] selectionArgs)
{
    ICursor cursor = null;
    String column = "_data";
    String[] projection = 
    {
        column
    };

    try
    {
        cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs, null);
        if (cursor != null && cursor.MoveToFirst())
        {
            int index = cursor.GetColumnIndexOrThrow(column);
            return cursor.GetString(index);
        }
    }
    finally
    {
        if (cursor != null)
            cursor.Close();
    }
    return null;
}

//Whether the Uri authority is ExternalStorageProvider.
public static bool isExternalStorageDocument(Android.Net.Uri uri)
{
    return "com.android.externalstorage.documents".Equals(uri.Authority);
}

//Whether the Uri authority is DownloadsProvider.
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
    return "com.android.providers.downloads.documents".Equals(uri.Authority);
}

//Whether the Uri authority is MediaProvider.
public static bool isMediaDocument(Android.Net.Uri uri)
{
    return "com.android.providers.media.documents".Equals(uri.Authority);
}

//Whether the Uri authority is Google Photos.
public static bool isGooglePhotosUri(Android.Net.Uri uri)
{
    return "com.google.android.apps.photos.content".Equals(uri.Authority);
}

OnActivityResult中获取实际路径:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == 0)
    {
        var uri = data.Data;
        string path = GetActualPathFromFile(uri);
        System.Diagnostics.Debug.WriteLine("Image path == " + path);

    }
}

这篇关于如何从Uri Xamarin Android获取实际路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆