Xamarin从图库中选择图像路径是空的

Bil*_*ull 1 android android-gallery xamarin.android xamarin xamarin.forms

使用此配方尝试从库中选择一个图像,然后将其上传到s3,但我的路径始终返回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;
        }
Run Code Online (Sandbox Code Playgroud)

mat*_*dev 12

这是一个从这个问题移植的工作实现,具体来说,这个答案.

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;
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

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

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

我已经使用了一个回调而不是返回路径,GetImage因为调用方法在调用之前会完成执行,OnActivityResult因此返回的路径永远不会有效.

  • 是的,如果有一家公司为了记录这些类型的东西而付出代价,那就太棒了,但是没有人踩到板上 (2认同)

小智 6

我将GetamaToImage方法从Xamarin 配方更改为下面的代码,现在它可以工作了!

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;
    }
Run Code Online (Sandbox Code Playgroud)