1

, используя этот рецепт, чтобы выбрать изображение из галереи, а затем загрузить его в s3, но мой путь всегда возвращает null.Xamarin Выберите изображение из галереи Path Null

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

     public string GetImage() 
     { 
      InitializeMediaPicker(); 

      return _imgPath; 
     } 

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

     private string GetPathToImage(Android.Net.Uri uri) 
     { 
      string path = null; 
      // The projection contains the columns we want to return in our query. 
      var projection = new[] { Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data }; 
      using (var cursor = ManagedQuery(uri, projection, null, null, 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; 
     } 

ответ

11

Вот рабочая реализация портированы из this question и, в частности, this answer.

Включите WRITE_EXTERNAL_STORAGE разрешение в манифесте для этого кода для работы.

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

Пример:

Button button = FindViewById<Button> (Resource.Id.myButton); 

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

Я использовал функцию обратного вызова, вместо того, чтобы вернуться на путь для GetImage как метод вызова закончит выполняться до OnActivityResult называется поэтому путь возвращается никогда не будет действительный.

+2

да и.т.д быть удивительным, если был как компании, которую вы заплатили, чтобы работать над документированием этих типов вещей, но не Idnó никого, подходя к плите – BillPull

+0

Абсолютно! Там много пробелов в продвинутых частях использования Xamarin, которые могут сделать с заполнением. Вам нужно, чтобы я расширил этот ответ больше BillPull? Если да, то какая дополнительная информация? – matthewrdev

+0

Он тоже работал для меня ... – Suchith

5

Я изменил метод GetPathToImage от Xamarin recipe до кода ниже, и теперь он работает!

private string GetPathToImage(Android.Net.Uri uri) 
    { 
     ICursor cursor = this.ContentResolver.Query(uri, null, null, null, null); 
     cursor.MoveToFirst(); 
     string document_id = cursor.GetString(0); 
     document_id = document_id.Split(':')[1]; 
     cursor.Close(); 

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

     return path; 
    } 
Смежные вопросы