I was following tutorial on this page http://channel9.msdn.com/Series/Windows-Phone-8-1-Development-for-Absolute-Beginners/Part-22-Storing-and-Retrieving-Serialized-Data because I want my app to store data in JSON file and then read it back. 2 things about the tutorial:
I press write button - works fine, then press read button and it also works, however, I close down win phone 8.1 emulator, open it again, press read button and I got the An exception of type 'System.IO.FileNotFoundException'exception! Why is that, I should have the file already on disk from previously running the app ? Or is does it get erased when I close down emulator ? Also I looked for the specified file on disk and cannot find it ! Any help ?
private const string JSONFILENAME = "data.json";
private async Task readJsonAsync()
{
string content = String.Empty;
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);
using (StreamReader reader = new StreamReader(myStream))
{
content = await reader.ReadToEndAsync();
}
resultTextBlock.Text = content;
}
private async Task writeJsonAsync()
{ // Notice that the write is ALMOST identical ... except for the serializer.
var myCars = buildObjectGraph();
var serializer = new DataContractJsonSerializer(typeof(List<Car>));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
JSONFILENAME,
CreationCollisionOption.ReplaceExisting))
{
serializer.WriteObject(stream, myCars);
}
resultTextBlock.Text = "Write succeeded";
}
When you close the Emulator its state is is not preserved, meaning that the apps that you tested are not there when you restart the emulator. Therefore, VS will make a new install when you open up the emulator again.
The same happens when you do a rebuild of your project. Then, VS will remove the app from the emulator and reinstall it from scratch. This in turn will also result in loosing your JSON file.
When you want to make sure that your data is preserved then don't close the emulator and just use Build from within VS (VS decides from time to time to rebuild your app though).
On order to test your app more properly I suggest you have a look at the Windows Phone Power Tools (http://wptools.codeplex.com/). There you can explicitly choose to install or update a given XAP package.
Related
What I want to do is to let user record his voice. The recording would be stored in local storage. User should be able to play the recording or replace it with a new one. And that's where I am having trouble.
Scenario A: there is no recording yet, this works fine... when user presses record button, these steps are taken to record the audio and then set it as source for media element.
// user starts recording by pressing a button
// create file with replace option
var audioStorageFile = await folder.CreateFileAsync(desiredName, CreationCollisionOption.ReplaceIfExists);
await mediaCapture.StartRecordToStorageFileAsync(audioEncodingProperties, audioStorageFile);
// user stops recording...
await mediaCapture.StopRecordAsync();
//...
audioStream = await audioStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
MyMediaElement.SetSource(audioStream, audioStorageFile.ContentType);
I can repeat this proccess as many times as I want and the old audio file is always replaced with the new one.
Scenario B: Recording already exists when I navigate to the page so I want to load it to the MediaElement right away (OnNavigatedTo event) like this
var audioStorageFile = await ApplicationData.Current.LocalFolder.GetFileAsync(desiredName);
audioStream = await audioStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
MyMediaElement.SetSource(audioStream, audioStorageFile.ContentType);
So user navigates to the page and file is already loaded to the MediaElement. The problem starts when user wants to replace the old recording. This piece of code is called before the code from Scenario A:
MyMediaElement.Stop();
MyMediaElement.Source = null;
When it reaches the line
var audioStorageFile = await folder.CreateFileAsync(desiredName, CreationCollisionOption.ReplaceIfExists);
UnauthorizedAccessException is thrown: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
It seems clear that the reason for the exception being thrown is that the file I'm trying to replace is in use. But I don't understand why and how to avoid it? Can anyone spot what I'm doing wrong? Thanks.
Add .Source = null before you create the file
MyMediaElement.Source = null;
var audioStorageFile = await folder.CreateFileAsync(desiredName, CreationCollisionOption.ReplaceIfExists);
If you're not in the habit of closing/disposing your Streams after you are done...you going to have a bad time.
To make sure dispose gets called, get in the habit of using using
Set your MediaElement like so
var audioStorageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("your_wav.wav");
using(Windows.Storage.Streams.IRandomAccessStream audio = await audioStorageFile.OpenAsync(FileAccessMode.Read))
{
this.myMed.SetSource(audio, audioStorageFile.ContentType);
}
Using the above methods, I was able to record over "your_wav.wav" no matter if it was already set as the Source of the MediaElement.
Ok, turns out that the problem actualy was that I was setting the source of the MediaElement before the MediaElement was added to the visual tree. I moved the code to set the media source from OnNavigatedTo to MediaElement.Loaded event and the problem was solved. I found the solution thanks to this question.
Im trying to open a file in a Windows Store App , with half the screen but so far i havent got it to work
this is the code im using
try
{
var options = new Windows.System.LauncherOptions();
options.DesiredRemainingView = Windows.UI.ViewManagement.ViewSizePreference.UseHalf;
var urii = new Uri(file.Path);
var success = await Windows.System.Launcher.LaunchUriAsync(urii, options);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
the file.path is
C:\Users\xxxx\AppData\Local\Packages\xxxxxxx\LocalState\Data\chap4_slides.ppt
and i can launch the file if i use
await Windows.System.Launcher.LaunchFileAsync(file, options);
but it doesnt uses half the screen
am i doing something wrong?
You're doing it right, but the DesiredRemainingView is explicitly a request not a command. As the remarks in the DesiredRemainingView docs say: By setting DesiredRemainingView, you aren't guaranteed a specific windowing behavior for the source app.
In your case I suspect you're not getting the desired view because your ppt file is launching in PowerPoint on the desktop.
I am creating Windows Phone 8.1 application, I am trying to open document using launcher, but getting exception, and document is not MS OFFICE document, it is created in other software. Here is my code.
string file = "readme.txt";
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
if (isf.FileExists(file))
{
isf.DeleteFile(file);
}
var filerun = await ApplicationData.Current.LocalFolder.CreateFileAsync(file);
await Launcher.LaunchFileAsync(await ApplicationData.Current.LocalFolder.GetFileAsync(file));
I am getting error like this:
"Can't be Open, File Format doesn't recognize"
and sometimes like this:
"Document has been damaged"
I do not know how to deal with this, I am stuck here, Any help would be greatly appreciated.
The file name without extension is "campaign rev 2", so the file pass to the launcher is definitely not "readme.txt".
You can pass a LauncherOptions.DisplayApplicationPicker to the LaunchFileAsync method.
var filerun = await ApplicationData.Current.LocalFolder.CreateFileAsync(file);
var options = new Windows.System.LauncherOptions(){ DisplayApplicationPicker = true};
await Launcher.LaunchFileAsync(filerun, options);
It will open a list of applications for you to choose from, so you can examine the file extension is actually .txt or .xls/.xlsx (Excel).
According to the documentation, this overload is available on Windows Phone 8.1. But I have not upgraded to 8.1 yet, so I can not give you a screenshot of the Application Picker.
Screenshot from the web. Hope this helps.
I want to use SkyDrive to backup some information.
But seems they have removed this namespace Microsoft.Live.Controls; from the new SDK, and all code samples and also answers here are outdated.
this reference also is outdated; there is no more LiveConnectClient
How can I simply backup files to SkyDrive after these changes?
(any code sample or reference is appreciated.)
It's not that hard, but there really are no references or tutorials. Everything that's below works just fine in my Windows Phone 8 project.
You need to include Microsoft.Live namespace after installing Live SDK.
First you have to create and initialize the client. After that, you log in and can send over some data:
LiveConnectClient client;
var auth = new LiveAuthClient("YourGeneratedKey");
var result = await auth.InitializeAsync(new [] {"wl.basic", "wl.signin", "wl.skydrive_update" });
// If you're not connected yet, that means you'll have to log in.
if(result.Status != LiveConnectSessionStatus.Connected)
{
// This will automatically show the login screen
result = await auth.LoginAsync(new [] {"wl.basic", "wl.signin", "wl.skydrive_update" });
}
if(result.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(result.Session);
}
Maybe the process above could be simplified, but it works for me.
Now you can use the client if everything went as planned. I've managed to successfully upload files from streams.
Let's say you've obtained a Stream to the file you want to send (I got that via WinRT file API on Windows Phone 8, IStorageFolder, then getting the file, then file.OpenStreamForReadAsync()), I'll just assume it's a text file for example purposes:
using(stream)
{
await client.UploadAsync("me/skydrive", "myfile.txt", stream, OverwriteOption.Overwrite);
}
Actually, I've used the overload that also accepts CancellationToken and IProgress<LiveOperationProgress>, mostly for progress notifications.
There, that should upload the file to the main directory on logged user's SkyDrive.
I'm trying to use C# with the Live Connect API to upload a blank (or one that says "test") text file to SkyDrive. The code I have so far:
LiveConnectClient client = await LiveSignin();
string folderID = await getFolder(client);
client.BackgroundUploadAsync(folderID, "pins.txt", "", OverwriteOption.Rename);
where LiveSignin() is a function that handles the sign in code and returns a LiveConnectClient, and getFolder(LiveConnectClient client) is a function that gets the folder ID that I'm trying to upload to.
That code throws an error about the blank string (third parameter on the last line) having to be a "Windows.Storage.Streams.IInputStream", but I can't seem to find any documentation on how to convert a String to an IInputStream, or, for that matter, much of any documentation on "IInputStream" that I can find.
With earlier versions of the Windows Runtime/Live Connect (on another project) I had used:
byte[] byteArray = System.Text.Encoding.Unicode.GetBytes(Doc);
MemoryStream stream = new MemoryStream(byteArray);
App.client.UploadCompleted += client_UploadCompleted;
App.client.UploadAsync(roamingSettings.Values["folderID"].ToString(), docTitle.Text + ".txt", stream);
but that throws a lot of errors now (most of them because UploadAsync has been replaced with BackgroundUploadAsync).
So, is there a way to convert a string to an IInputStream, or do I not even need to use an IInputStream? If my method just doesn't work, how would one upload a blank text file to SkyDrive from a C# Metro app? (developing in Visual Studio 2012 Express on the evaluation of Windows 8 Enterprise, if that makes much of a difference)
EDIT: I finally found "Stream.AsInputStream", but now I'm getting the same error as this
An unhandled exception of type 'System.AccessViolationException'
occurred in Windows.Foundation.winmd
Additional information: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt
the code now:
LiveConnectClient client = await LiveSignin();
string folderID = await getFolder(client);
Stream OrigStream = new System.IO.MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes("test"));
LiveOperationResult result = await client.BackgroundUploadAsync(folderID, "pins.txt", OrigStream.AsInputStream(), OverwriteOption.Rename);
Hi
Had same problem today and as far as I can see the only solution to this problem is to write your text into a local file first and then upload it.
My solution looks like this:
var tmpFile= await ApplicationData.Current.
LocalFolder.CreateFileAsync
("tmp.txt", CreationCollisionOption.ReplaceExisting);
using (var writer = new StreamWriter(await tmpFile.OpenStreamForWriteAsync()))
{
await writer.WriteAsync("File content");
}
var operationResult =
await client.BackgroundUploadAsync(folderId, tmpFile.Name, tmpFile,
OverwriteOption.Overwrite);