问题描述
我想做的只是使用mono touch / mono droid和mvvmcross将照片上传到网络服务,希望在某种程度上我只需要为android和IOS编写一次代码:)
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 :)
我最初的想法是让用户选择一个图像(在Android中使用意图)获取图像的路径。然后使用MvxResourceLoader resourceLoader从路径打开一个流,然后使用restsharp创建一个包含该流的帖子请求。
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.
然而,当用户选择时,我已经碰壁了路径是例如的图像/外部/图像/媒体/ 13。使用MvxResourceLoader resourceLoader时,此路径会导致文件未找到异常。
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.
为什么我得到异常或有更好的方法来实现我的目标? / p>
Any ideas to why I get the exception or is there an better way to achieve my goal?
推荐答案
这就是我最终做到的方式 - 谢谢stuart和所有链接:)
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;
}
}
}
这篇关于使用mvvmcross和mono touch将照片上传到网络服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!