3

What I want to do is simply to upload a photo to a webservice using mono touch/mono droid and mvvmcross, hopefully in a way so I only have to write the code once for both android and IOS :)

My initial idea is to let the user pick an image (in android using an intent) get the path for the image. Then use MvxResourceLoader resourceLoader to open an stream from the path and then use restsharp for creating a post request with the stream.

However I already hit a wall, when the user picks an image the path is e.g. "/external/images/media/13". this path results in a file not found exception when using the MvxResourceLoader resourceLoader.

Any ideas to why I get the exception or is there an better way to achieve my goal?

Bjarke
  • 1,283
  • 11
  • 36

2 Answers2

3

This is how I ended up doinging it - thank you stuart and to all the links :)

public class PhotoService :IPhotoService, IMvxServiceConsumer<IMvxPictureChooserTask>,IMvxServiceConsumer<IAppSettings>
    {
        private const int MaxPixelDimension = 300;
        private const int DefaultJpegQuality = 64;

        public void ChoosePhotoForEventItem(string EventGalleryId, string ItemId)
        { 
        this.GetService<IMvxPictureChooserTask>().ChoosePictureFromLibrary(
               MaxPixelDimension,
                DefaultJpegQuality,
               delegate(Stream stream) { UploadImage(stream,EventGalleryId,ItemId); },
                () => { /* cancel is ignored */ });

        }

        private void UploadImage(Stream stream, string EventGalleryId, string ItemId)
        {
            var settings = this.GetService<IAppSettings>();
            string url = string.Format("{0}/EventGallery/image/{1}/{2}", settings.ServiceUrl, EventGalleryId, ItemId);
            var uploadImageController = new UploadImageController(url);

            uploadImageController.OnPhotoAvailableFromWebservice +=PhotoAvailableFromWebservice;

            uploadImageController.UploadImage(stream,ItemId);

        }
    }

    public class PhotoStreamEventArgs : EventArgs
    {
        public Stream PictureStream { get; set; }

        public Action<string> OnSucessGettingPhotoFileName { get; set; }

        public string URL { get; set; }
    }

     public class UploadImageController : BaseController, IMvxServiceConsumer<IMvxResourceLoader>, IMvxServiceConsumer<IErrorReporter>, IMvxServiceConsumer<IMvxSimpleFileStoreService>
    {

        public UploadImageController(string uri)
            : base(uri)
        {

        }
        public event EventHandler<PhotoStreamEventArgs> OnPhotoAvailableFromWebservice;


        public void UploadImage(Stream stream, string name)
        {
            UploadImageStream(stream, name);
        }


        private void UploadImageStream(Stream obj, string name)
        {

            var request = new RestRequest(base.Uri, Method.POST);

            request.AddFile("photo", ReadToEnd(obj), name + ".jpg", "image/pjpeg");

            //calling server with restClient
            var restClient = new RestClient();

            try
            {

                this.ReportError("Billedet overføres", ErrorEventType.Warning);

                restClient.ExecuteAsync(request, (response) =>
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        //upload successfull
                        this.ReportError("Billedet blev overført", ErrorEventType.Warning);
                        if (OnPhotoAvailableFromWebservice != null)
                        {
                            this.OnPhotoAvailableFromWebservice(this, new PhotoStreamEventArgs() { URL = base.Uri });
                        }
                    }
                    else
                    {
                        //error ocured during upload
                        this.ReportError("Billedet kunne ikke overføres \n" + response.StatusDescription, ErrorEventType.Warning);
                    }
                });
            }
            catch (Exception e)
            {

                this.ReportError("Upload completed succesfully...", ErrorEventType.Warning);
                if (OnPhotoAvailableFromWebservice != null)
                {
                    this.OnPhotoAvailableFromWebservice(this, new PhotoStreamEventArgs() { URL = url });
                }
            }


        }

        //method for converting stream to byte[]

        public byte[] ReadToEnd(System.IO.Stream stream)
        {
            long originalPosition = stream.Position;
            stream.Position = 0;
            try
            {
                byte[] readBuffer = new byte[4096];
                int totalBytesRead = 0;
                int bytesRead;
                while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                {
                    totalBytesRead += bytesRead;
                    if (totalBytesRead == readBuffer.Length)
                    {

                        int nextByte = stream.ReadByte();
                        if (nextByte != -1)
                        {
                            byte[] temp = new byte[readBuffer.Length * 2];
                            Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                            Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                            readBuffer = temp;
                            totalBytesRead++;
                        }

                    }
                }

                byte[] buffer = readBuffer;
                if (readBuffer.Length != totalBytesRead)
                {
                    buffer = new byte[totalBytesRead];
                    Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                }
                return buffer;
            }
            finally
            {
                stream.Position = originalPosition;
            }
        }

    }
Bjarke
  • 1,283
  • 11
  • 36
1

Try:

Community
  • 1
  • 1
Stuart
  • 66,722
  • 7
  • 114
  • 165