save the image in storage file in windows phone 8 - windows-phone-8

I'm making a windows phone 8 app of an app I made for windows store, and I am using PhotoChooser task to let the user upload a profile picture.
In the store version i used streams and FileOpenPicker, but i don't know how to use streams with PhotoChooser task.
This is how i did it in windows store, and its perfect:
StorageFile image;
public bunForm()
{
image = null;
this.InitializeComponent();
}
private async void choosePic(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
openPicker.FileTypeFilter.Clear();
openPicker.FileTypeFilter.Add(".bmp");
openPicker.FileTypeFilter.Add(".png");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".jpg");
// Open a stream for the selected file
var file = await openPicker.PickSingleFileAsync();
if (file != null)
{
image = file;
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
bunPic.Visibility = Visibility.Visible;
// Ensure a file was selected
if (file != null)
{
// Ensure the stream is disposed once the image is loaded
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);// bitmapImage.UriSource.ToString();
bunPic.Source = bitmapImage;
}
}
}
}
And here is how i'm trying it at windows Phone 8:
But (openPicker.PickSingleFileAsync();) line gives me error.
public BunForm()
{
InitializeComponent();
image = null;
this.photoChooserTask = new PhotoChooserTask();
this.photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
}
StorageFile image;
private void choosePic(object sender, RoutedEventArgs e)
{
photoChooserTask.Show();
}
private async void photoChooserTask_Completed(object sender, PhotoResult e)
{
//this is the only line that gives me error
var file = await openPicker.PickSingleFileAsync();
///
if (file != null)
{
image = file;
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
if (file != null)
{
// Ensure the stream is disposed once the image is loaded
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
MessageBox.Show(e.ChosenPhoto.Length.ToString());
//Code to display the photo on the page in an image control named myImage.
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
myImage.Source = bmp;
}
}
}
Debug.WriteLine("pic done");
}
I was wondering how i can save the image in storage file in windows phone 8?

As noted on MSDN pages - OpenFilePicker cannot be used in C# WP8 apps, but you can use the PhotoChooserTask with ease for uploadng the profile picture:
// first invoke the task somewhere
PhotoChooserTask task = new PhotoChooserTask();
task.Completed += task_Completed;
task.Show();
// handle the result
async void task_Completed(object sender, PhotoResult e)
{
// no photo selected
if (e.ChosenPhoto == null) return;
// get the file stream and file name
Stream photoStream = e.ChosenPhoto;
string fileName = Path.GetFileName(e.OriginalFileName);
// persist data into isolated storage
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream current = await file.OpenStreamForWriteAsync())
{
await photoStream.CopyToAsync(current);
}
...
// how to read the data later
StorageFile file2 = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
Stream imageStream = await file2.OpenStreamForReadAsync();
// display the file as image
BitmapImage bi = new BitmapImage();
bi.SetSource(imageStream);
// assign the bitmap to Image in XAML: <Image x:Name="img"/>
img.Source = bi;
}

Accoriding to this
Windows Phone 8
This API is supported in native apps only.
You can't use FileOpenPicker class.
There are already answers to the problem OpenFilePicker not working

Related

trying to access an external JSON file using netwonsoft in mvc4 c#

I'm trying to read an external json to display data on screen. What am I doing worng here?
public void QuarterlyReport(object sender, EventArgs e)
{
JObject qData1 = JObject.Parse(System.IO.File.ReadAllText(#"~/json/quarterlyData.json"));
// read JSON directly from a file
using (StreamReader file = System.IO.File.OpenText(#"~/json/quarterlyData.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
JObject Qdata2 = (JObject) JToken.ReadFrom(reader);
}
string Qdata = Newtonsoft.Json.JsonConvert.SerializeObject(qData1);
}
public async Task<FileStreamResult> Index()
{
var _reportingService = new ReportingService("https://mysite.jsreportonline.net", "myemail#gmail.com", "password");
var report = await _reportingService.RenderAsync("VyxOYwH7Ze", new { Qdata });
//add the stream to be used by browser
MemoryStream ms = new MemoryStream();
//copy whatever JS is sending to us
report.Content.CopyTo(ms);
//start at content point
ms.Position = 0;
//send this to browser
return File(ms, report.ContentType.MediaType);
}
I can't seem to get the vaule into the variable Qdata. What is it that I am doing wrong in the method?
The line where you declare Qdata:
string Qdata = Newtonsoft.Json.JsonConvert.SerializeObject(qData1);
is not in the same scope as this line:
var report = await _reportingService.RenderAsync("VyxOYwH7Ze", new { Qdata });
Yes, the problem was that
JObject qData1 = JObject.Parse(System.IO.File.ReadAllText(#"~/json/quarterlyData.json"));
And
string Qdata = Newtonsoft.Json.JsonConvert.SerializeObject(qData1);
Needed to be in the same scope as
var report = await _reportingService.RenderAsync("VyxOYwH7Ze", new { Qdata });

WriteableBitmapExtension crashes app on device

I have added a WriteableBitmapExtension via NuGet to my Windows Phone 8.1 WinRT app. I have functions to capture an image from camera and save it to picture library. I tried rotate captured image before save and I found solution here
WriteableBitmap crashes program with no message?. Everything works fine on emulator but when I run my app on Nokia Lumia 630 it crashes few seconds after taking a photo without debbuger message. Can anyone help me with this issue? Here is my code of taking photo:
public WriteableBitmap Image
{
get
{
return this.image;
}
set
{
this.image = value;
this.RaisePropertyChanged(() => this.Image);
}
}
private async void TakePhoto()
{
using (var stream = new InMemoryRandomAccessStream())
{
var imgEncodingProperties = ImageEncodingProperties.CreateJpeg();
var img = BitmapFactory.New(640, 480);
await this.MediaCapture.CapturePhotoToStreamAsync(imgEncodingProperties, stream);
stream.Seek(0);
img.SetSource(stream);
WriteableBitmapExtensions.DrawLine(img, 10, 10, 300, 300, Colors.Black);
this.Image = img.Rotate(90);
this.TurnOffCaptureMode();
}
}
private void TurnOffCaptureMode()
{
this.MediaCapture.StopPreviewAsync();
this.IsInCaptureMode = false;
}
Alternate solution is here.
1 Open file Picket use build in camera to take picture.
var openPicker = new FileOpenPicker();
openPicker.ContinuationData["Action"] = "SendPicture";
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".png");
openPicker.PickSingleFileAndContinue();
***2. In app.xaml.cs you will get captured image. as below.***
public void Continue(IContinuationActivatedEventArgs args)
{
if(args.Kind == ActivationKind.PickFileContinuation)
{
var openPickerContinuationArgs = args as FileOpenPickerContinuationEventArgs;
// Recover the "Action" info we stored in ContinuationData
string action = (string) openPickerContinuationArgs.ContinuationData["Action"];
if(openPickerContinuationArgs.Files.Count > 0)
{
// TODO: Get the files here
}
else
{
// TODO: Write code here to handle picker cancellation.
}
}
}

Windows Phone: How to load html in webview from a local file

I have a html string and it has local css,js paths. But Html is not working with these local paths. We searced but in every example, they have loaded html with writing inline. But I have to work disconnect and there is so much css,js assests. If i write inline, i am worried about it will load slow and i think it so senseless. Then i decided to change a local html file and load html from that file.
How can i load html from a local file?
This is my example code:
StorageFolder localFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
string desiredName = "mobile.html";
StorageFile newFile =
await localFolder.CreateFileAsync(desiredName,CreationCollisionOption.OpenIfExists);
using (var stream = await newFile.OpenStreamForWriteAsync())
{
stream.Write(fileBytes, 0, fileBytes.Length);
}
webViewFormResponse.Source = new Uri(newFile.Path);
newFile.Path like this: C:\Data\Users\DefApps\APPDATA\Local\Packages\9f4082ad-ad69-4cb8-8749-751ee4c5e46d_x2xndhe6jjw20\LocalState\mobile.html
You can use the NavigateToLocalStreamUri method of the WebView
e.g.
In WebView Loaded event
private void WebView_Loaded(object sender, RoutedEventArgs e)
{
Uri uri = MyWebView.BuildLocalStreamUri("LocalData", "mobile.html");
LocalUriResolver resolver = new LocalUriResolver();
MyWebView.NavigateToLocalStreamUri(uri, resolver);
}
And the Uri resolver class
public sealed class LocalUriResolver : IUriToStreamResolver
{
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
{
if (uri == null)
{
throw new Exception();
}
string path = uri.AbsolutePath;
return GetContent(path).AsAsyncOperation();
}
private async Task<IInputStream> GetContent(string uriPath)
{
try
{
Uri localUri = new Uri("ms-appdata:///local" + uriPath);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(localUri);
IRandomAccessStream stream = await file.OpenReadAsync();
return stream.GetInputStreamAt(0);
}
catch (Exception)
{
throw new Exception("Invalid path");
}
}
}

Windows Phone 8 append to JSON file

I'm working on a Windows Phone 8 app.
I'm having issue appending to my JSON file.
It works fine if I keep the app open but once I close it and come back in it starts back writing from the beginning of the file.
Relevant code:
private async void btnSave_Click(object sender, RoutedEventArgs e)
{
// Create a entry and intialize some values from textbox...
GasInfoEntries _entry = null;
_entry = new GasInfoEntries();
_entry.Gallons = TxtBoxGas.Text;
_entry.Price = TxtBoxPrice.Text;
_GasList.Add(_entry);
//TxtBlockPricePerGallon.Text = (double.Parse(TxtBoxGas.Text) / double.Parse(TxtBoxPrice.Text)).ToString();
// Serialize our Product class into a string
string jsonContents = JsonConvert.SerializeObject(_GasList);
// Get the app data folder and create or open the file we are storing the JSON in.
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile textfile = await localFolder.CreateFileAsync("gasinfo.json", CreationCollisionOption.OpenIfExists); //if get await operator error add async to class (btnsave)
//open file
using (IRandomAccessStream textstream = await textfile.OpenAsync(FileAccessMode.ReadWrite))
{
//write JSON string
using (DataWriter textwriter = new DataWriter(textstream))
//using (DataWriter textwriter = new DataWriter(textstream))
{
textwriter.WriteString(jsonContents);
await textwriter.StoreAsync(); //writes buffer to store
}
}
}
private async void btnShow_Click(object sender, RoutedEventArgs e)
{
StorageFolder localfolder = ApplicationData.Current.LocalFolder;
try
{
// Getting JSON from file if it exists, or file not found exception if it does not
StorageFile textfile = await localfolder.GetFileAsync("gasinfo.json");
using (IRandomAccessStream textstream = await textfile.OpenReadAsync())
{
//read text stream
using (DataReader textreader = new DataReader(textstream))
{
//get size ...not sure what for think check the file size (lenght) then based on next 2 commands waits until its all read
uint textlength = (uint)textstream.Size;
await textreader.LoadAsync(textlength);
//read it
string jsonContents = textreader.ReadString(textlength);
// deserialize back to gas info
_GasList = JsonConvert.DeserializeObject<List<GasInfoEntries>>(jsonContents) as List<GasInfoEntries>;
displayGasInfoEntries();
}
}
}
catch
{
txtShow.Text = "something went wrong";
}
}
private void displayGasInfoEntries()
{
txtShow.Text = "";
StringBuilder GasString = new StringBuilder();
foreach (GasInfoEntries _entry in _GasList)
{
GasString.AppendFormat("Gallons: {0} \r\n Price: ${1} \r\n", _entry.Gallons, _entry.Price); // i think /r/n means Return and New line...{0} and {1} calls "variables" in json file
}
txtShow.Text = GasString.ToString();
}
Thanks
Do you call the btnShow_Click each time you've started the app? Because otherwise the _GasList will be empty; if you now call the btnSave_Click all previous made changes will be lost.
So please make sure, that you restore the previously saved json data before you add items to the _GasList.

windows phone 8: how to download xml file from web and save it to local?

I would like to download a xml file from web, then save it to the local storage but I do not know how to do that. Please to help me clearly or give me an example. Thank you.
Downloading a file is a huge subject and can be done in many ways. I assume that you know the Uri of the file you want to download, and want you mean by local is IsolatedStorage.
I'll show three examples how it can be done (there are also other ways).
1. The simpliest example will dowload string via WebClient:
public static void DownloadFileVerySimle(Uri fileAdress, string fileName)
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, ev) =>
{
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
using (StreamWriter writeToFile = new StreamWriter(ISF.CreateFile(fileName)))
writeToFile.Write(ev.Result);
};
client.DownloadStringAsync(fileAdress);
}
As you can see I'm directly downloading string (ev.Result is a string - that is a disadventage of this method) to IsolatedStorage.
And usage - for example after Button click:
private void Download_Click(object sender, RoutedEventArgs e)
{
DownloadFileVerySimle(new Uri(#"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt");
}
2. In the second method (simple but more complicated) I'll use again WebClient and I'll need to do it asynchronously (if you are new to this I would suggest to read MSDN, async-await on Stephen Cleary blog and maybe some tutorials).
First I need Task which will download a Stream from web:
public static Task<Stream> DownloadStream(Uri url)
{
TaskCompletionSource<Stream> tcs = new TaskCompletionSource<Stream>();
WebClient wbc = new WebClient();
wbc.OpenReadCompleted += (s, e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wbc.OpenReadAsync(url);
return tcs.Task;
}
Then I'll write my method downloading a file - it also need to be async as I'll use await DownloadStream:
public enum DownloadStatus { Ok, Error };
public static async Task<DownloadStatus> DownloadFileSimle(Uri fileAdress, string fileName)
{
try
{
using (Stream resopnse = await DownloadStream(new Uri(#"http://filedress/myfile.txt", UriKind.Absolute)))
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (ISF.FileExists(fileName)) return DownloadStatus.Error;
using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))
resopnse.CopyTo(file, 1024);
return DownloadStatus.Ok;
}
}
catch { return DownloadStatus.Error; }
}
And usage of my method for example after Button click:
private async void Downlaod_Click(object sender, RoutedEventArgs e)
{
DownloadStatus fileDownloaded = await DownloadFileSimle(new Uri(#"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt");
switch (fileDownloaded)
{
case DownloadStatus.Ok:
MessageBox.Show("File downloaded!");
break;
case DownloadStatus.Error:
default:
MessageBox.Show("There was an error while downloading.");
break;
}
}
This method can have problems for example if you try to download very big file (example 150 Mb).
3. The third method - uses WebRequest with again async-await, but this method can be changed to download files via buffer, and therefore not to use too much memory:
First I'll need to extend my Webrequest by a method that will asynchronously return a Stream:
public static class Extensions
{
public static Task<Stream> GetRequestStreamAsync(this WebRequest webRequest)
{
TaskCompletionSource<Stream> taskComplete = new TaskCompletionSource<Stream>();
webRequest.BeginGetRequestStream(arg =>
{
try
{
Stream requestStream = webRequest.EndGetRequestStream(arg);
taskComplete.TrySetResult(requestStream);
}
catch (Exception ex) { taskComplete.SetException(ex); }
}, webRequest);
return taskComplete.Task;
}
}
Then I can get to work and write my Downloading method:
public static async Task<DownloadStatus> DownloadFile(Uri fileAdress, string fileName)
{
try
{
WebRequest request = WebRequest.Create(fileAdress);
if (request != null)
{
using (Stream resopnse = await request.GetRequestStreamAsync())
{
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (ISF.FileExists(fileName)) return DownloadStatus.Error;
using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))
{
const int BUFFER_SIZE = 10 * 1024;
byte[] buf = new byte[BUFFER_SIZE];
int bytesread = 0;
while ((bytesread = await resopnse.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
file.Write(buf, 0, bytesread);
}
}
return DownloadStatus.Ok;
}
}
return DownloadStatus.Error;
}
catch { return DownloadStatus.Error; }
}
Again usage:
private async void Downlaod_Click(object sender, RoutedEventArgs e)
{
DownloadStatus fileDownloaded = await DownloadFile(new Uri(#"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt");
switch (fileDownloaded)
{
case DownloadStatus.Ok:
MessageBox.Show("File downloaded!");
break;
case DownloadStatus.Error:
default:
MessageBox.Show("There was an error while downloading.");
break;
}
}
Those methods of course can be improved but I think this can give you an overview how it can look like. The main disadvantage of these methods may be that they work in foreground, which means that when you exit your App or hit start button, downloading stops. If you need to download in background you can use Background File Transfers - but that is other story.
As you can see you can reach your goal in many ways. You can read more about those methods on many pages, tutorials and blogs, compare an choose the most suitable.
Hope this helps. Happy coding and good luck.