【问题标题】:Xamarin Choose Image From Gallery Path is NullXamarin 从库路径中选择图像为空
【发布时间】:2014-10-27 22:17:25
【问题描述】:

使用此配方尝试从图库中选择一张图片,然后将其上传到 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;
        }

【问题讨论】:

    标签: android xamarin xamarin.android android-gallery xamarin.forms


    【解决方案1】:

    这是一个从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 之前完成执行,因此返回的路径永远不会有效。

    【讨论】:

    • 是的,如果有像这样的公司,你付钱来记录这些类型的事情,但没有人站出来,那就太棒了
    • 绝对! Xamarin 的高级使用部分有很多空白可以填补。你需要我更多地扩展这个答案吗 BillPull?如果有,还有哪些额外信息?
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多