首页 > 解决方案 > 如何在 Xamarin Android 中一次从图库中选择多个图像(复选框)?

问题描述

您好,有一个使用 C# 的 Xamarin Android 项目。目前我正在使用 await CrossMedia.Current.PickPhotoAsync() 方法上传图像。但是,它没有在图像旁边提供一个复选框供我选择多个。如何管理选择多个图像并一起上传?

标签: c#xamarin.android

解决方案


你可以自己实现它。

1.将这些方法添加到您的 MainActivity.cs 文件中

    public static int OPENGALLERYCODE = 100;
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);

        //If we are calling multiple image selection, enter into here and return photos and their filepaths.
        if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
        {
            List<string> images = new List<string>();

            if (data != null)
            {
                //Separate all photos and get the path from them all individually.
                ClipData clipData = data.ClipData;
                if (clipData != null)
                {
                    for (int i = 0; i < clipData.ItemCount; i++)
                    {
                        ClipData.Item item = clipData.GetItemAt(i);
                        Android.Net.Uri uri = item.Uri;
                        var path = GetRealPathFromURI(uri);


                        if (path != null)
                        {
                            images.Add(path);
                        }
                    }
                }
                else
                {
                    Android.Net.Uri uri = data.Data;
                    var path = GetRealPathFromURI(uri);

                    if (path != null)
                    {
                        images.Add(path);
                    }
                }


            }
        }
    }

    /// <summary>
    ///     Get the real path for the current image passed.
    /// </summary>
    public String GetRealPathFromURI(Android.Net.Uri contentURI)
    {
        try
        {
            ICursor imageCursor = null;
            string fullPathToImage = "";

            imageCursor = ContentResolver.Query(contentURI, null, null, null, null);
            imageCursor.MoveToFirst();
            int idx = imageCursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);

            if (idx != -1)
            {
                fullPathToImage = imageCursor.GetString(idx);
            }
            else
            {
                ICursor cursor = null;
                var docID = DocumentsContract.GetDocumentId(contentURI);
                var id = docID.Split(':')[1];
                var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
                var projections = new string[] { MediaStore.Images.ImageColumns.Data };

                cursor = ContentResolver.Query(MediaStore.Images.Media.InternalContentUri, projections, whereSelect, new string[] { id }, null);
                if (cursor.Count == 0)
                {
                    cursor = ContentResolver.Query(MediaStore.Images.Media.ExternalContentUri, projections, whereSelect, new string[] { id }, null);
                }
                var colData = cursor.GetColumnIndexOrThrow(MediaStore.Images.ImageColumns.Data);
                cursor.MoveToFirst();
                fullPathToImage = cursor.GetString(colData);
            }
            return fullPathToImage;
        }
        catch (Exception ex)
        {
            Toast.MakeText(Xamarin.Forms.Forms.Context, "Unable to get path", ToastLength.Long).Show();
        }
        return null;
    }

2.在您要打开选择器的特定活动中调用以下内容

 public void OpenGallery()
    {
        try
        {
            var imageIntent = new Intent(Intent.ActionPick);
            imageIntent.SetType("image/*");
            imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
            imageIntent.SetAction(Intent.ActionGetContent);
            this.StartActivityForResult(Intent.CreateChooser(imageIntent, "Select photo"), OPENGALLERYCODE);
            Toast.MakeText(this, "Tap and hold to select multiple photos.", ToastLength.Short).Show();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            Toast.MakeText(this, "Error. Can not continue, try again.", ToastLength.Long).Show();
        }
    }


    void ClearFileDirectory()
    {
        var directory = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), ImageHelpers.collectionName).Path.ToString();

        if (Directory.Exists(directory))
        {
            var list = Directory.GetFiles(directory, "*");
            if (list.Length > 0)
            {
                for (int i = 0; i < list.Length; i++)
                {
                    File.Delete(list[i]);
                }
            }
        }
    }


   //collectionName is the name of the folder in your Android Pictures directory.
    public static readonly string collectionName = "TmpPictures";

    public string SaveFile(byte[] imageByte, string fileName)
    {
        var fileDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), collectionName);
        if (!fileDir.Exists())
        {
            fileDir.Mkdirs();
        }

        var file = new Java.IO.File(fileDir, fileName);
        System.IO.File.WriteAllBytes(file.Path, imageByte);

        return file.Path;
    }

    public string CompressImage(string path)
    {
        byte[] imageBytes;

        //Get the bitmap.
        var originalImage = BitmapFactory.DecodeFile(path);

        //Set imageSize and imageCompression parameters.
        var imageSize = .86;
        var imageCompression = 67;

        //Resize it and then compress it to Jpeg.
        var width = (originalImage.Width * imageSize);
        var height = (originalImage.Height * imageSize);
        var scaledImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, true);

        using (MemoryStream ms = new MemoryStream())
        {
            scaledImage.Compress(Bitmap.CompressFormat.Jpeg, imageCompression, ms);
            imageBytes = ms.ToArray();
        }

        originalImage.Recycle();
        originalImage.Dispose();
        GC.Collect();

        return SaveFile(imageBytes, Guid.NewGuid().ToString());
    }

推荐阅读