Get stream from absolute Uri - windows-phone-7

I'm working with Windows Phone 7 and I have a very difficult problem. Please help me !
I want to get a stream form an absolute uri (from web) of a png image. But GetResourceStream method work only with relative uri. Then I found imagetool form http://imagetools.codeplex.com/ but to now my problem is not still solved.
Could anyone give me a solution ?

How about using HttpWebRequest and HttpWebResponse?
var uri = new Uri("http://chriskoenig.net/wp-content/uploads/2011/04/givecamp_125125_ad.jpg", UriKind.Absolute);
HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
request.BeginGetResponse((ar) =>
{
var response = request.EndGetResponse(ar);
Dispatcher.BeginInvoke(() =>
{
using (var stream = response.GetResponseStream())
{
var image = new BitmapImage();
image.SetSource(stream);
MyImage.Source = image;
}
});
}, null);

Try this simple Code Image stream from Absolute url and store to isolated storage
namespace eQuadrigaWP7
{
public class ItemViewModel : INotifyPropertyChanged
{
private string _imgURL;
public string imgURL
{
get
{
return _imgURL;
}
set
{
if (value != _imgURL)
{
_imgURL = value;
}
}
}
private BitmapImage _Image;
public BitmapImage Iimage
{
get
{
return _Image;
}
set
{
if (value != _Image)
{
_Image = value;
}
}
}
public void LoadIimage()
{
if (this.imgURL == null) throw new Exception("Error equadriga log");
HttpWebRequest downloadthumbnailrequest = (HttpWebRequest)WebRequest.Create(new Uri(this._imgURL)); ///this is main
DownloadThumbNailState thumbnailState = new DownloadThumbNailState();
thumbnailState.AsyncRequest = downloadthumbnailrequest;
downloadthumbnailrequest.BeginGetResponse(new AsyncCallback(HandleThumNailDownLoadResponse),
thumbnailState);
}
private void HandleThumNailDownLoadResponse(IAsyncResult asyncResult)
{
DownloadThumbNailState thumbnailState = (DownloadThumbNailState)asyncResult.AsyncState;
HttpWebRequest downloadthumbnailrequest = (HttpWebRequest)thumbnailState.AsyncRequest;
thumbnailState.AsyncResponse = (HttpWebResponse)downloadthumbnailrequest.EndGetResponse(asyncResult);
Stream imageStream = thumbnailState.AsyncResponse.GetResponseStream();
byte[] b = new byte[imageStream.Length];
imageStream.Read(b,0,Convert.ToInt32(imageStream.Length));
imageStream.Close();
MemoryStream ms = new MemoryStream(b);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(ms);
String tempJPEG = "logo.jpg";
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempJPEG);
WriteableBitmap wb = new WriteableBitmap(bmp);
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
this.Iimage = bmp;
}
});
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class DownloadThumbNailState
{
public HttpWebRequest AsyncRequest { get; set; }
public HttpWebResponse AsyncResponse { get; set; }
}
}
}
ItemViewModel imageitem = new ItemViewModel();
imageitem.imgURL = "http://www.yoursite.in/bilder/9780199738663/titel.jpg";
imageitem.LoadIimage();

Try this one,
BitmaiImage bmp=new BitmaiImage();
Image image=new Image();
Uri url = new Uri("http://Ur url", UriKind.Absolute);
HttpWebRequest reqest = (HttpWebRequest)WebRequest.Create(url);
reqest.BeginGetResponse(DownloadImageCallback, reqest);
void DownloadImageCallback(IAsyncResult result)
{
HttpWebRequest req = (HttpWebRequest)result.AsyncState;
HttpWebResponse responce = (HttpWebResponse)req.EndGetResponse(result);
Stream s = responce.GetResponseStream();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
bmp.SetSource(s);
image.Source=bmp;
});
}

Related

xamarin.forms - Upload multiple images and files using multipart/form data

In my xamarin.forms app. I am using Media.plugin to select images from gallery and camera.And also file picker plugin to select files like pdf,jpg etc from file manager.User can select multiple images and files and It will store in an observable collection.In this observable collection I have the path of images as well as files. Where I am stuck is I want to send these data to rest API by using multipart/form data.How can I send these multiple files to the server? Any help is appreciated.
My ObservableCollection
public ObservableCollection<SelectedDocumentModel> DataManager
{
get
{
return _selectedfile ?? (_selectedfile = new ObservableCollection<SelectedDocumentModel>());
}
}
My Data Model
public class SelectedDocumentModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string FileName { get; set; }
public string Path { get; set; }
public ImageSource SelectedImage { get; set; }
public object Tasks { get; internal set; }
private bool isLoadingVisible = false;
public bool IsLoadingVisible
{
get
{
return isLoadingVisible;
}
set
{
if (value != null)
{
isLoadingVisible = value;
NotifyPropertyChanged("IsLoadingVisible");
}
}
}
}
Selecting image using media.plugin and allocating to my observable collection
var Filename = Path.GetFileName(file.Path);
var FilePath = file.Path;
var newList = new SelectedDocumentModel()
{
FileName = Filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path = FilePath
};
DataManager.Add(newList);
Selecting file from file manager using filepicker plugin and assign to observablecollection
var FilePath = pickedFile.FilePath;
var newList = new SelectedDocumentModel()
{
FileName = filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path= FilePath
};
DataManager.Add(newList);
EDIT
This is what I should do using httpclient.Currently these are written using RestSharp.
var client = new RestClient("{{api_url}}/MYData");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "bearer {{token}}");
request.AddHeader("Content-Type", "application/json");
request.AlwaysMultipartFormData = true;
request.AddParameter("ids", " [{\"id\":1,\"person_id\":5}]");
request.AddParameter("title", " Test");
request.AddParameter("description", " Test");
request.AddParameter("send_text_message", " true");
request.AddParameter("text_message", " Test");
request.AddParameter("notification_type"," global");
request.AddParameter("my_files", "[
{
\"name\": \"abc.jpg\",
\"key\": \"1583307983694\"
}
]");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
What I have done by the way suggested by Lucas Zhang - MSFT.
try {
MultipartFormDataContent multiContent = new MultipartFormDataContent();
foreach (SelectedDocumentModel model in SelectedFileData)
{
byte[] byteArray = Encoding.UTF8.GetBytes(model.Path);
MemoryStream stream = new MemoryStream(byteArray);
HttpContent fileStreamContent1 = new StreamContent(stream);
fileStreamContent1.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = model.FileName,
FileName = model.FileName
};
fileStreamContent1.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
multiContent.Add(fileStreamContent1);
}
multiContent.Add(new StringContent(notificationdetails[0]), "title");
multiContent.Add(new StringContent(notificationdetails[1]), "description");
multiContent.Add(new StringContent(notificationdetails[3]), "type");
multiContent.Add(new StringContent(notificationdetails[7]), "send_text_message");
multiContent.Add(new StringContent(notificationdetails[2]), "text_message");
multiContent.Add(new StringContent(notificationdetails[8]), "send_email");
multiContent.Add(new StringContent(notificationdetails[9]), "notification_type");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer",Settings.AuthToken);
var response = await client.PostAsync(url, multiContent);
var responsestr = response.Content.ReadAsStringAsync().Result;
await DisplayAlert("Result", responsestr.ToString(), "ok");
}
catch (Exception ex)
{
await DisplayAlert("Result", ex.Message.ToString(), "ok");
}
unfortunately it not working.It not sending the data as I intend.
How can I upload each files as multipart/formdata on a button click.?Any help is appriciated.
You could use MultipartFormDataContent to add multiple images,and use ContentDispositionHeaderValue.Parameters to add the values of your Data.
Usage
var fileStream = pickedFile.GetStream();
var newList = new SelectedDocumentModel()
{
FileName = filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path= FilePath,
Data = fileStream ,
};
MultipartFormDataContent multiContent = new MultipartFormDataContent();
foreach(var SelectedDocumentModel model in DataManager)
{
HttpContent fileStreamContent1 = new StreamContent(model.Data);
fileStreamContent1.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = "File",
FileName = "xxx.jpg"
};
fileStreamContent1.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
multiContent.Add(fileStreamContent1);
multiContent.Add(new StringContent(model.Title), "model.Title");
multiContent.Add(new StringContent(model.Description), "model.Description");
multiContent.Add(new StringContent(model.Detail), "model.Detail");
}
// Send (url = url of api) ,use httpclient
var response = await client.PostAsync(url, multiContent);

Download and Save PDF for viewing

Im trying to download a PDF document from my app and display it in IBooks or at least make it available to read some how when its completed downloading.
I followed the download example from Xamarin which allows me download the PDF and save it locally. Its being save in the wrong encoding also.
This is what I've tried so far.
private void PdfClickHandler()
{
var webClient = new WebClient();
webClient.DownloadStringCompleted += (s, e) => {
var text = e.Result; // get the downloaded text
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string localFilename = $"{_blueways}.pdf";
// writes to local storage
File.WriteAllText(Path.Combine(documentsPath, localFilename), text);
InvokeOnMainThread(() => {
new UIAlertView("Done", "File downloaded and saved", null, "OK", null).Show();
});
};
var url = new Uri(_blueway.PDF);
webClient.Encoding = Encoding.UTF8;
webClient.DownloadStringAsync(url);
}
Do not use DownloadStringAsync for "binary" data, use DownloadDataAsync:
Downloads the resource as a Byte array from the URI specified as an asynchronous operation.
private void PdfClickHandler ()
{
var webClient = new WebClient ();
webClient.DownloadDataCompleted += (s, e) => {
var data = e.Result;
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string localFilename = $"{_blueways}.pdf";
File.WriteAllBytes (Path.Combine (documentsPath, localFilename), data);
InvokeOnMainThread (() => {
new UIAlertView ("Done", "File downloaded and saved", null, "OK", null).Show ();
});
};
var url = new Uri ("_blueway.PDF");
webClient.DownloadDataAsync (url);
}
// Retrieving the URL
var pdfUrl = new Uri("url.pdf"); //enter your PDF path here
// Open PDF URL with device browser to download
Device.OpenUri(pdfUrl);
//First Create Model Class FileDownload
public class FileDownload
{
public string FileUrl { get; set; }
public string FileName { get; set; }
}
//Create a view in xaml file for button on which we need to perform download functionality
<ImageButton BackgroundColor="Transparent" Clicked="DownloadFile_Clicked" x:Name="ImgFileReportDownload_ViewResult" IsVisible="False">
<ImageButton.Source>
<FontImageSource Glyph=""
Color="#1CBB8C"
Size="30"
FontFamily="{StaticResource FontAwesomeSolid}">
</FontImageSource>
</ImageButton.Source>
</ImageButton>
//Created a method in xaml.cs to download File on the click of button
private async void DownloadFile_Clicked(object sender, EventArgs e)
{
var status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
if (status == PermissionStatus.Granted)
{
Uri uri = new Uri(fileReportNameViewResult);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
FileDownload fileDownload = new FileDownload();
fileDownload.FileName = filename;
fileDownload.FileUrl = fileReportNameViewResult;
MessagingCenter.Send<FileDownload>(fileDownload, "Download");
}
else
{
status = await Permissions.RequestAsync<Permissions.StorageWrite>();
if (status != PermissionStatus.Granted)
{
await DisplayAlert("Permission Denied!", "\nPlease go to your app settings and enable permissions.", "Ok");
return;
}
}
}
//In MainActivity.cs , create a method
private void MessagingCenter()
{
Xamarin.Forms.MessagingCenter.Subscribe<FileDownload>(this, "Download", (s) =>
{
NotificationID += 4;
var intent = new Intent(this, typeof(Service.DownloadManager));
intent.PutExtra("url", s.FileUrl);
intent.PutExtra("name", s.FileName);
_layout.SetMinimumHeight(3000);
_layout.Bottom = 350; ;
Snackbar.Make(_layout, "Document is Downloading.", Snackbar.LengthShort)
.Show();
StartService(intent);
});
}
//Create a class DownloadManager.cs in Service folder , copy all the below code and paste , just change the Namespace
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace App.Droid.Service
{
[Service]
public class DownloadManager : Android.App.Service
{
AndroidNotificationManager NotificationManager = new AndroidNotificationManager();
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
Task.Run(() =>
{
int messageId = ++MainActivity.NotificationID;
string url = intent.GetStringExtra("url");
string filename = intent.GetStringExtra("name");
string extension = url.Substring(url.LastIndexOf('.'));
if (!filename.EndsWith(extension))
{
filename += extension;
}
NotificationManager.ScheduleNotification(filename, "", messageId);
String TempFileName = "";
try
{
HttpWebRequest Http = (HttpWebRequest)WebRequest.Create(url);
WebResponse Response = Http.GetResponse();
long length = Response.ContentLength;
var stream = Response.GetResponseStream();
string baseDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
//string baseDir = Android.App.Application.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
//string baseDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
//string baseDir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
baseDir = Path.Combine(baseDir, filename.Substring(filename.LastIndexOf('/') + 1).Replace(' ', '_'));
Directory.CreateDirectory(baseDir);
//string filePath = Path.Combine(documentsPath, name);
if (filename.Length > 18)
{
TempFileName = filename.Substring(0, 18) + "...";
}
else
{
TempFileName = filename;
}
FileInfo fi = new FileInfo(Path.Combine(baseDir, filename.Substring(filename.LastIndexOf('/') + 1).Replace(' ', '_')));
var fis = fi.OpenWrite();
long count = 0;
int begpoint = 0;
bool iscancelled = false;
MessagingCenter.Subscribe<CancelNotificationModel>(this, "Cancel", sender =>
{
if (messageId == sender.ID)
{
iscancelled = true;
}
});
while (true)
{
try
{
if (iscancelled == true)
{
break;
}
// Read file
int bytesRead = 0;
byte[] b = new byte[1024 * 1024];
bytesRead = stream.Read(b, begpoint, b.Length);
if (bytesRead == 0)
break;
fis.Write(b, 0, bytesRead);
fis.Flush();
count += bytesRead;
System.Diagnostics.Debug.WriteLine(count + "-" + length);
if (count >= length)
break;
NotificationManager.ChangeProgress(TempFileName, (int)((count * 100) / length), messageId);
}
catch (Exception ex)
{
Http = (HttpWebRequest)WebRequest.Create(url);
WebHeaderCollection myWebHeaderCollection = Http.Headers;
Http.AddRange(count, length - 1);
Response = Http.GetResponse();
stream = Response.GetResponseStream();
}
}
fis.Close();
NotificationManager.RemoveNotification(messageId);
if (iscancelled == false)
{
new AndroidNotificationManager().DownloadCompleted(filename, "Download Completed", Path.Combine(baseDir, filename), ++messageId);
}
}
catch (Exception ex)
{
NotificationManager.RemoveNotification(messageId);
NotificationManager.FileCancelled(filename, "Download Cancelled, Please try again", ++messageId);
}
});
return StartCommandResult.NotSticky;
}
public override void OnDestroy()
{
}
}
public class CancelNotificationModel
{
public int ID { get; set; }
}
}
//Create a class AndroidNotificationManager.cs in Service folder
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.Core.App;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Essentials;
using AndroidApp = Android.App.Application;
namespace App.Droid.Service
{
public class AndroidNotificationManager
{
const string channelId = "default";
const string channelName = "Default";
const string channelDescription = "The default channel for notifications.";
const int pendingIntentId = 0;
public const string TitleKey = "title";
public const string MessageKey = "message";
bool channelInitialized = false;
NotificationManager manager;
NotificationCompat.Builder builder;
public event EventHandler NotificationReceived;
public void Initialize()
{
CreateNotificationChannel();
}
public void RemoveNotification(int messageid)
{
manager.Cancel(messageid);
}
public int ScheduleNotification(string title, string message, int messageId, bool isInfinite = false)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
Intent intent = new Intent(AndroidApp.Context, typeof(MainActivity));
intent.PutExtra(TitleKey, title);
intent.PutExtra(MessageKey, message);
PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId, intent, PendingIntentFlags.OneShot);
builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentTitle(title)
.SetContentText(message)
.SetPriority(NotificationCompat.PriorityLow)
.SetVibrate(new long[] { 0L })
.SetProgress(100, 0, isInfinite)
.SetSmallIcon(Resource.Drawable.checkcircle);
var notification = builder.Build();
manager.Notify(messageId, notification);
return messageId;
}
public void ChangeProgress(string filename, int progress, int messageId)
{
try
{
var actionIntent1 = new Intent();
actionIntent1.SetAction("Cancel");
actionIntent1.PutExtra("NotificationIdKey", messageId);
var pIntent1 = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, actionIntent1, PendingIntentFlags.CancelCurrent);
var ProgressBuilder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetSmallIcon(Resource.Drawable.checkcircle)
.SetContentTitle(filename)
.SetVibrate(new long[] { 0L })
.AddAction(Resource.Drawable.checkcircle, "Cancel", pIntent1)
.SetPriority(NotificationCompat.PriorityLow)
.SetProgress(100, progress, false)
.SetContentText(progress + "%")
.SetAutoCancel(false);
System.Diagnostics.Debug.WriteLine(progress);
manager.Notify(messageId, ProgressBuilder.Build());
}
catch
{
}
}
public void DownloadCompleted(string filenametitle, string Message, string filepath, int messageId)
{
try
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
var CompletedBuilder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentTitle(filenametitle)
.SetContentText(Message)
.SetAutoCancel(true)
.SetSmallIcon(Resource.Drawable.checkcircle);
Intent it = OpenFile(filepath, filenametitle);
if (it != null)
{
PendingIntent contentIntent =
PendingIntent.GetActivity(AndroidApp.Context,
pendingIntentId,
it,
PendingIntentFlags.OneShot
);
CompletedBuilder.SetContentIntent(contentIntent);
}
var notification = CompletedBuilder.Build();
manager.Notify(messageId, notification);
}
catch (Exception ex)
{
}
}
public void FileCancelled(string filenametitle, string Message, int messageId)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
var CompletedBuilder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetContentTitle(filenametitle)
.SetContentText(Message)
.SetAutoCancel(true)
.SetSmallIcon(Resource.Drawable.checkcircle)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate);
var notification = CompletedBuilder.Build();
manager.Notify(messageId, notification);
}
public void ReceiveNotification(string title, string message)
{
}
void CreateNotificationChannel()
{
manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelNameJava = new Java.Lang.String(channelName);
var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Low)
{
Description = channelDescription
};
manager.CreateNotificationChannel(channel);
}
channelInitialized = true;
}
public Intent OpenFile(string filePath, string fileName)
{
try
{
string application = "";
string extension = fileName.Substring(fileName.IndexOf('.'));
switch (extension.ToLower())
{
case ".doc":
case ".docx":
application = "application/msword";
break;
case ".pdf":
application = "application/pdf";
break;
case ".xls":
case ".xlsx":
application = "application/vnd.ms-excel";
break;
case ".jpg":
case ".jpeg":
case ".png":
application = "image/jpeg";
break;
case ".mp4":
application = "video/mp4";
break;
default:
application = "*/*";
break;
}
Java.IO.File file = new Java.IO.File(filePath);
bool isreadable =
file.SetReadable(true);
string ApplicationPackageName = AppInfo.PackageName;
var context = Android.App.Application.Context;
var component = new Android.Content.ComponentName(context, Java.Lang.Class.FromType(typeof(AndroidX.Core.Content.FileProvider)));
var info = context.PackageManager.GetProviderInfo(component, Android.Content.PM.PackageInfoFlags.MetaData);
var authority = info.Authority;
Android.Net.Uri uri = AndroidX.Core.Content.FileProvider.GetUriForFile(Android.App.Application.Context, authority, file);
Intent intent = new Intent(Intent.ActionView);
System.IO.File.AppendAllText((filePath + "backdebug.txt"), System.Environment.NewLine + "Point 3 uri done ");
intent.SetDataAndType(uri, application);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
intent.AddFlags(ActivityFlags.NoHistory);
intent.AddFlags(ActivityFlags.NewTask);
System.IO.File.AppendAllText((filePath + "backdebug.txt"), System.Environment.NewLine + "Point 4open file last ");
return intent;
}
catch (Exception ex)
{
Intent it = new Intent();
it.PutExtra("ex", ex.Message);
System.IO.File.AppendAllText((filePath + "backdebug.txt"), System.Environment.NewLine + "Point 4 uri done " + ex.Message);
return it;
}
}
}
}
Here is the sample code to download file in PCL Xamarin from remote server.
I have used PCLStorage library package which is available in Nuget. You just need download and install in your project.
public async void Downloadfile(string Url)
{
try
{
Uri url = new Uri(Url);
var client = new HttpClient();
IFolder rootfolder = FileSystem.Current.LocalStorage;
IFolder appfolder = await rootfolder.CreateFolderAsync("Download", CreationCollisionOption.OpenIfExists);
IFolder dbfolder = await appfolder.CreateFolderAsync("foldername", CreationCollisionOption.OpenIfExists);
IFile file = await dbfolder.CreateFileAsync(strReport_name, CreationCollisionOption.ReplaceExisting);
using (var fileHandler = await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite))
{
var httpResponse = await client.GetAsync(url);
byte[] dataBuffer = await httpResponse.Content.ReadAsByteArrayAsync();
await fileHandler.WriteAsync(dataBuffer, 0, dataBuffer.Length);
}
}
catch (Exception ex)
{
throw ex;
}
}

How to convert image to base64 string in Windows Phone?

I am developing a windows phone application in which I have to convert image to base64 string and I have to pass that string through Web Service. So I tried many Ways, but I cant able to send it as everytime I am getting error as "Target Invocation error". With this code I can choose the image from library but I cant send through web service.
I used the following code to covert the image:
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
BitmapImage image = new BitmapImage();
image.SetSource(e.ChosenPhoto);
this.imageTribute.Source = image;
byte[] bytearray = null;
using (MemoryStream ms = new MemoryStream())
{
if (imageTribute.Source == null)
{
}
else
{
WriteableBitmap wbitmp = new WriteableBitmap((BitmapImage)imageTribute.Source);
wbitmp.SaveJpeg(ms, 40, 40, 0, 82);
bytearray = ms.ToArray();
}
}
strimage = Convert.ToBase64String(bytearray);
}
So please if anyone knows about that, help me out. Thanx in advance.
EDIT
void uploadphoto()
{
WebClient webClient1 = new WebClient();
webClient1.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient1_DownloadStringCompleted);
webClient1.DownloadStringAsync(new Uri("Web Service"));
}
void webClient1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var rootobject1 = JsonConvert.DeserializeObject<RootObject1>(e.Result);
int error = rootobject1.response.errorFlag;
string message = rootobject1.response.msg;
if (error == 0)
{
MessageBox.Show(message);
}
else
{
MessageBox.Show(message);
}
}
public class Response1
{
public int errorFlag { get; set; }
public string msg { get; set; }
public List<string> uploadedImageNames { get; set; }
}
public class RootObject1
{
public Response1 response { get; set; }
}
private void ImageUpload(object sender, RoutedEventArgs e)
{
//MessageBoxResult mb = MessageBox.Show("Select the mode of uploading the picture", "", MessageBoxButton.OKCancel);
Popup popup = new Popup();
photoSelection photo = new photoSelection();
popup.Child = photo;
popup.IsOpen = true;
photo.camera.Click += (s, args) =>
{
photoCameraCapture.Show();
popup.IsOpen = false;
};
photo.library.Click += (s, args) =>
{
photoChooserTask.Show();
popup.IsOpen = false;
};
}
EDIT
Here I uploaded the stack trace of my error. So please check and reply me.
A Target Invocation Exception error tells you that the application crashed while invoking a method which could be many things. The real error is in the InnerException.
Look at the InnerException property of the TargetInvocationException object. This will show you the stack trace and the actual error thrown.
Get your file into stream either from resource or from isolatedStorage
//getting file from resource
var resource = Application.GetResourceStream(new Uri("image.jpg", UriKind.Relative));
//get Stream Data
StreamReader streamReader = new StreamReader(resource.Stream);
//initializing bytearray to stream length
byte[] imageData = new byte[streamReader.Length];
//wriing from stream to imagdata
streamReader.Read(imageData, 0, imageData.Length);
streamReader.Close();
Use isolatedStorageFile to read from isolated storage
now you have your image data in imageData and to convert it into base64 use:
var baseString = Convert.ToBase64String(imageData);

uploading photo to a webservice with mvvmcross and mono touch

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?
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;
}
}
}
Try:
Issues taking images and showing them with MvvmCross on WP
Need an example of take a Picture with MonoDroid and MVVMCross
https://github.com/Redth/WshLst/ - uses Xam.Mobile for it's picture taking

WP7 - POST form with an image

I need to send an image from the Windows Phone 7 to some e-mail addresses.
I use this class to submit text values to a PHP script, wich parses data and sends a formatted e-mail to the addresses.
The problem is that I can't figure out how to send an image to that script, to attach the image to the e-mail. The PHP script can be changed in any way. If I have an Image object, how can I change this class to allow sending images?
public class PostSubmitter
{
public string url { get; set; }
public Dictionary<string, string> parameters { get; set; }
public PostSubmitter() { }
public void Submit()
{
// Prepare web request...
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
System.IO.Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Prepare Parameters String
string parametersString = "";
foreach (KeyValuePair<string, string> parameter in parameters)
{
parametersString = parametersString + (parametersString != "" ? "&" : "") + string.Format("{0}={1}", parameter.Key, parameter.Value);
}
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(parametersString);
// Write to the request stream.
postStream.Write(byteArray, 0, parametersString.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
//Action<string> act = new Action<string>(DisplayResponse);
//this.Dispatcher.BeginInvoke(act, responseString);
}
I use the class in this way:
Dictionary<string, string> data = new Dictionary<string, string>()
{
{"nom", nom.Text},
{"cognoms", cognoms.Text},
{"email", email.Text},
{"telefon", telefon.Text}
};
PostSubmitter post = new PostSubmitter() { url = "http://example.com/parserscript.php", parameters = data };
post.Submit();
Thank you very much!
I've converted the above code to the following, I'm sure it will help:
public class PostSubmitter
{
public string url { get; set; }
public Dictionary<string, object> parameters { get; set; }
string boundary = "----------" + DateTime.Now.Ticks.ToString();
public PostSubmitter() { }
public void Submit()
{
// Prepare web request...
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
myRequest.Method = "POST";
myRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
writeMultipartObject(postStream, parameters);
postStream.Close();
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
}
public void writeMultipartObject(Stream stream, object data)
{
StreamWriter writer = new StreamWriter(stream);
if (data != null)
{
foreach (var entry in data as Dictionary<string, object>)
{
WriteEntry(writer, entry.Key, entry.Value);
}
}
writer.Write("--");
writer.Write(boundary);
writer.WriteLine("--");
writer.Flush();
}
private void WriteEntry(StreamWriter writer, string key, object value)
{
if (value != null)
{
writer.Write("--");
writer.WriteLine(boundary);
if (value is byte[])
{
byte[] ba = value as byte[];
writer.WriteLine(#"Content-Disposition: form-data; name=""{0}""; filename=""{1}""", key, "sentPhoto.jpg");
writer.WriteLine(#"Content-Type: application/octet-stream");
//writer.WriteLine(#"Content-Type: image / jpeg");
writer.WriteLine(#"Content-Length: " + ba.Length);
writer.WriteLine();
writer.Flush();
Stream output = writer.BaseStream;
output.Write(ba, 0, ba.Length);
output.Flush();
writer.WriteLine();
}
else
{
writer.WriteLine(#"Content-Disposition: form-data; name=""{0}""", key);
writer.WriteLine();
writer.WriteLine(value.ToString());
}
}
}
}
To convert an image from the camera to an byte array I've used the follwing:
private void photoChooserTask_Completed(object sender, PhotoResult e)
{
try
{
BitmapImage image = new BitmapImage();
image.SetSource(e.ChosenPhoto);
foto.Source = image;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(image);
// write an image into the stream
Extensions.SaveJpeg(btmMap, ms, image.PixelWidth, image.PixelHeight, 0, 100);
byteArray = ms.ToArray();
}
}
catch (ArgumentNullException) { /* Nothing */ }
}
And I use the class this way:
Dictionary<string, object> data = new Dictionary<string, object>()
{
{"nom", nom.Text},
{"cognoms", cognoms.Text},
{"email", email.Text},
{"telefon", telefon.Text},
{"comentari", comentari.Text},
{"foto", byteArray},
};
PostSubmitter post = new PostSubmitter() { url = "http://example.com/parserscript.php", parameters = data};
post.Submit();
I don't know if it's the best way to send an image from the phone to a server, but I couldn't find anything, so I made my own class just reading this and that, and it has taken me several days. If anybody wants to improve the code or write any comment will be welcomed.
There are lots of questions/answers on here to help already
e.g.
Post with WebRequest - although i couldn't spot any specifically for photos.
Perhaps the best way is to use something like Hammock on Codeplex - http://hammock.codeplex.com/ - or perhaps something like RESTSharp - http://restsharp.org/ - they provide standard REST POST functions.
e.g. if you look within Hammock, then you'll find others who've posted images direct from the camera to tumblr - see http://hammock.codeplex.com/discussions/235650
The above code works perfect. I just use a different method to convert the file to an array of bytes which works perfect with Audio
public static class FileHelper
{
public static 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;
}
}
}

Resources