2015-04-20 130 views
0

我一直在嘗試在網上找到多種解決方案,並且尚未找到可用的解決方案。Xamarin Android - 從圖庫中選擇圖片並獲取路徑

我試圖從圖庫中選擇一個圖像,然後上傳它。現在,我只是想弄清楚如何獲得圖像的路徑。

我首先嚐試了配方,發現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; 
    } 

但是,路徑仍爲空。

如何獲取所選圖像的路徑?

回答

-1

像這樣實現此方法'GetPathToImage'以提取設備上的圖像路徑並顯示。

輔助方法GetPathToImage添加到您的活動有以下內容:

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; 

}

希望這會幫助你。

+0

這就是我鏈接的食譜說要做的事情。這也返回null。 – Gavin

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); 
     } 
    } 
} 

這個類應該能夠處理任何烏里你拋出它並返回FilePath。不要忘記將命名空間導入到您的活動中!希望有所幫助。改編自here

相關問題