【问题标题】:Xamarin Android - Choose image from gallery and get its pathXamarin Android - 从图库中选择图像并获取其路径
【发布时间】:2015-04-20 05:41:16
【问题描述】:

我一直在尝试在网上找到的多种解决方案,但还没有找到一种有效的解决方案。

我正在尝试从图库中选择一张图片,然后上传。目前,我只是想弄清楚如何获取图像的路径。

我首先尝试了找到 here 的配方,但是,它总是返回 null 作为答案。

我现在正在尝试使用从另一个 SO 问题中找到的代码。

    public static readonly int ImageId = 1000;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);


        GetImage(((b, p) => {
            Toast.MakeText(this, "Found path: " + p, ToastLength.Long).Show();
        }));
    }

    public delegate void OnImageResultHandler(bool success, string imagePath);

    protected OnImageResultHandler _imagePickerCallback;
    public void GetImage(OnImageResultHandler callback)
    {
        if (callback == null) {
            throw new ArgumentException ("OnImageResultHandler callback cannot be null.");
        }

        _imagePickerCallback = callback;
        InitializeMediaPicker();
    }

    public void InitializeMediaPicker()
    {
        Intent = new Intent();
        Intent.SetType("image/*");
        Intent.SetAction(Intent.ActionGetContent);
        StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), 1000);
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        if ((requestCode != 1000) || (resultCode != Result.Ok) || (data == null)) {
            return;
        }

        string imagePath = null;
        var uri = data.Data;
        try {
            imagePath = GetPathToImage(uri);
        } catch (Exception ex) {
            // Failed for some reason.
        }

        _imagePickerCallback (imagePath != null, imagePath);
    }

    private string GetPathToImage(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 = ManagedQuery(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;
    }

但是,路径仍然为空。

如何获取选中图片的路径?

【问题讨论】:

    标签: c# android mono xamarin xamarin.android


    【解决方案1】:

    从以下位置更改 imagePath:

    imagePath = GetPathToImage(uri);
    

    到

    imagePath = UriHelper.GetPathFromUri(this, data.Data);
    

    然后将以下类添加到您的项目中:

    using Android.Content;
    using Android.Database;
    using Android.OS;
    using Android.Provider;
    using DroidEnv = Android.OS.Environment;
    using DroidUri = Android.Net.Uri;
    
    namespace MyApp.Helpers
    {
        public static class UriHelper
        {
            /// <summary>
            /// Method to return File path of a Gallery Image from URI.
            /// </summary>
            /// <param name="context">The Context.</param>
            /// <param name="uri">URI to Convert from.</param>
            /// <returns>The Full File Path.</returns>
            public static string GetPathFromUri(Context context, DroidUri uri)
            {
    
                //check here to KITKAT or new version
                // bool isKitKat = Build.VERSION.SdkInt >= Build.VERSION_CODES.Kitkat;
                bool isKitKat = Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat;
    
                // DocumentProvider
                if (isKitKat && DocumentsContract.IsDocumentUri(context, uri))
                {
    
                    // ExternalStorageProvider
                    if (isExternalStorageDocument(uri))
                    {
                        string docId = DocumentsContract.GetDocumentId(uri);
                        string[] split = docId.Split(':');
                        string type = split[0];
    
                        if (type.Equals("primary", System.StringComparison.InvariantCultureIgnoreCase))
                        {
                            return DroidEnv.ExternalStorageDirectory + "/" + split[1];
                        }
                    }
                    // DownloadsProvider
                    else if (isDownloadsDocument(uri))
                    {
    
                        string id = DocumentsContract.GetDocumentId(uri);
                        DroidUri ContentUri = ContentUris.WithAppendedId(
                          DroidUri.Parse("content://downloads/public_downloads"), long.Parse(id));
    
                        return GetDataColumn(context, ContentUri, null, null);
                    }
                    // MediaProvider
                    else if (isMediaDocument(uri))
                    {
                        string docId = DocumentsContract.GetDocumentId(uri);
                        string[] split = docId.Split(':');
                        string type = split[0];
    
                        DroidUri 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(context, contentUri, selection, selectionArgs);
                    }
                }
                // MediaStore (and general)
                else if (uri.Scheme.Equals("content", System.StringComparison.InvariantCultureIgnoreCase))
                {
    
                    // Return the remote address
                    if (isGooglePhotosUri(uri))
                        return uri.LastPathSegment;
    
                    return GetDataColumn(context, uri, null, null);
                }
                // File
                else if (uri.Scheme.Equals("file", System.StringComparison.InvariantCultureIgnoreCase))
                {
                    return uri.Path;
                }
    
                return null;
            }
    
           /// <summary>
           /// Get the value of the data column for this URI. This is useful for
           /// MediaStore URIs, and other file-based ContentProviders.
           /// </summary>
           /// <param name="context">The Context.</param>
           /// <param name="uri">URI to Query</param>
           /// <param name="selection">(Optional) Filter used in the Query.</param>
           /// <param name="selectionArgs">(Optional) Selection Arguments used in the Query.</param>
           /// <returns>The value of the _data column, which is typically a File Path.</returns>
            private static string GetDataColumn(Context context, DroidUri 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;
            }
    
            /// <param name="uri">The URI to Check.</param>
            /// <returns>Whether the URI Authority is ExternalStorageProvider.</returns>
            private static bool isExternalStorageDocument(DroidUri uri)
            {
                return "com.android.externalstorage.documents".Equals(uri.Authority);
            }
    
    
             /// <param name="uri">The URI to Check.</param>
             /// <returns>Whether the URI Authority is DownloadsProvider.</returns>
            private static bool isDownloadsDocument(DroidUri uri)
            {
                return "com.android.providers.downloads.documents".Equals(uri.Authority);
            }
    
    
             /// <param name="uri">The URI to Check.</param>
             /// <returns>Whether the URI Authority is MediaProvider.</returns>
            private static bool isMediaDocument(DroidUri uri)
            {
                return "com.android.providers.media.documents".Equals(uri.Authority);
            }
    
    
             /// <param name="uri">The URI to check.</param>
             /// <returns>Whether the URI Authority is Google Photos.</returns>
            private static bool isGooglePhotosUri(DroidUri uri)
            {
                return "com.google.android.apps.photos.content".Equals(uri.Authority);
            }
        }
    }
    

    这个类应该能够处理你扔给它的任何 Uri 并返回 FilePath。不要忘记将命名空间导入到您的活动中!希望有帮助。改编自here

    【讨论】:

      【解决方案2】:

      像这样实现这个方法'GetPathToImage'来提取设备上图像的路径并显示。

      将辅助方法 GetPathToImage 添加到您的 Activity 中,内容如下:

      private string GetPathToImage(Uri uri)
       {
         string path = null;
         // The projection contains the columns we want to return in our query.
         string[] projection = new[]       {Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data };
           using (ICursor cursor = ManagedQuery(uri, projection, null, null,  null))
           {
             if (cursor != null)
             {
               int columnIndex =   cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
              cursor.MoveToFirst();
              path = cursor.GetString(columnIndex);
             }
           }
      
      return path;
      

      }

      希望这会对您有所帮助。

      【讨论】:

      • 这就是我链接的食谱所说的。这也返回 null。
      猜你喜欢
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多