Launching PDF reader on windows phone 8 - c#

I'm trying to launch pdf reader with the code below but it does not work. Can somebody help me?
private async Task<StorageFile> WriteData(string fileName, byte[] data)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
s.Close();
}
return file;
}
private async Task<bool> OpenPdf(StorageFile file)
{
var uri = new Uri(file.Path, UriKind.RelativeOrAbsolute);
bool result = await Windows.System.Launcher.LaunchUriAsync(uri);
return result;
}
private async void FetchPdf() {
// Fetch pdf bytes to network
//....
StorageFile file = await WriteData("test.pdf", data);
if (file != null) {
bool result = await OpenPdf(file);
if (result)
Debug.WriteLine("Success");
else
Debug.WriteLine("Cannot open pdf file.");
}
}
result is always false and so launcher is not presented.
I used LaunchUriAsync because LaunchFileAsync is not implemented on Windows Phone.

LaunchUriAsync isn't supported on Windows Phone 8 per the documentation. It throws an exception if called
You can use Windows.System.Launcher.LaunchFileAsync to launch a StorageFile.
This code works for example (assming there's a file called "metro.pdf" in the project, with the Build Action set to Content, with Copy to Output Directory set to Copy if Newer).
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("metro.pdf");
Windows.System.Launcher.LaunchFileAsync(pdf);

Called the API and saved the byte array to file
public static async void WriteDataToIsolatedStorageFile(string fileName, byte[] data)
{
using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = storageFile.OpenFile(fileName, FileMode.Create))
{
if ((data != null) && (data.Length > 0))
{
await stream.WriteAsync(data, 0, data.Length);
}
}
}
}
opened the file in pdf reader using
private async void StartExternalPDFApp()
{
StorageFolder localFolder = await FileManager.FindDirectory(FileManager.RelativeStorageDirectoryLocalStorage);
StorageFile storageFile = await localFolder.GetFileAsync(PdfFileName);
await Windows.System.Launcher.LaunchFileAsync(storageFile);
}
localFolder is Windows.Storage.ApplicationData.Current.LocalFolder

just put the anyFile.pdf in Assets folder, and make its build action to Content, and then Just make the function Async ... and then Put "await" before Windows.System.Launcher.LaunchFileAsync(pdf);
it worked fine for me. Nice.
See this.
private async void privacyPolicy_Click(object sender, EventArgs e)
{
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("PrivacyPolicy.pdf");
await Windows.System.Launcher.LaunchFileAsync(pdf);
}

Related

Problem with asynchronous function when writing bytes into a file

I am developing an UWP app where you can download videos from YouTube and convert them to a mp3 file. My problem here is that the process of writing the bytes of the downloaded video to the created .mp4 file freezes the application although it is marked as async and all the necessary function calls are marked with the await keyword.
The following function has been assigned to the Click attribute of the button:
private async void DownloadMp3File(object sender, RoutedEventArgs e)
{
string url = youtubeUrl.Text;
if (!string.IsNullOrEmpty(url) && url.Contains("youtube"))
{
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
StorageFolder storageFolder = KnownFolders.MusicLibrary;
var youTube = YouTube.Default; // starting point for YouTube actions
var video = await youTube.GetVideoAsync(url); // gets a Video object with info about the video
string videoPath = Path.Combine(savePath, video.FullName);
string mp3Path = Path.Combine(savePath, videoPath.Replace(".mp4", ".mp3"));
StorageFile videoFile = await storageFolder.CreateFileAsync(Path.GetFileName(videoPath), CreationCollisionOption.ReplaceExisting);
StorageFile mp3File = await storageFolder.CreateFileAsync(Path.GetFileName(mp3Path), CreationCollisionOption.ReplaceExisting);
await WriteBytesIntoVideoFile(videoFile, video).ConfigureAwait(false);
await ConvertMp4ToMp3(videoFile, mp3File);
await videoFile.DeleteAsync();
}
}
During debugging I managed to find out where the app would freeze. It freezes exactly during the time of writing the bytes of the YouTube video into the mp4 file.
The function WriteBytesIntoVideoFile writes the bytes of the downloaded video into the created video file. before this implementation I used FileIO.WriteBytesAsync but it is the same behaviour:
public async Task WriteBytesIntoVideoFile(StorageFile videoFile, YouTubeVideo downloadedVideo)
{
//await FileIO.WriteBytesAsync(videoFile, downloadedVideo.GetBytes());
var outputStream = await videoFile.OpenAsync(FileAccessMode.ReadWrite);
using (var dataWriter = new DataWriter(outputStream))
{
foreach (var byt in downloadedVideo.GetBytes())
{
dataWriter.WriteByte(byt);
}
await dataWriter.StoreAsync();
await outputStream.FlushAsync();
}
}
Finally the convert method which converts the mp4 to a mp3. It uses the MediaTranscoder to achieve this.
public async Task ConvertMp4ToMp3(IStorageFile videoFile, IStorageFile mp3File)
{
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Auto);
MediaTranscoder transcoder = new MediaTranscoder();
PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(videoFile, mp3File, profile);
if (prepareOp.CanTranscode)
{
await prepareOp.TranscodeAsync();
//transcodeOp.Progress +=
// new AsyncActionProgressHandler<double>(TranscodeProgress);
//transcodeOp.Completed +=
// new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
}
else
{
switch (prepareOp.FailureReason)
{
case TranscodeFailureReason.CodecNotFound:
System.Diagnostics.Debug.WriteLine("Codec not found.");
break;
case TranscodeFailureReason.InvalidProfile:
System.Diagnostics.Debug.WriteLine("Invalid profile.");
break;
default:
System.Diagnostics.Debug.WriteLine("Unknown failure.");
break;
}
}
}
Could anyone explain to me why the app freezes during the process of writing the bytes of the downloaded video to the mp4 file? Any help is appreciated.

WP 8.1 - How to save an image to Isolated Storage if know it's URL

I have the image URL.
How can I save it into Isolated Storage in WP 8.1.
Can I trigger both save it and then share it onto Facebook with only one button?
This is my code - which work well following Burak Kaan Köse's:
public async void GetImage()
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
if (folder != null)
{
StorageFile file = await folder.CreateFileAsync("imagefile", CreationCollisionOption.ReplaceExisting);
string url = imgUri[fLFl.SelectedIndex].ToString();
HttpClient client = new HttpClient();
byte[] fileContent = await client.GetByteArrayAsync(url); ; // This is where you set your content as byteArray
Stream fileStream = await file.OpenStreamForWriteAsync();
fileStream.Write(fileContent, 0, fileContent.Length);
fileStream.Flush();
fileStream.Dispose();
}
}
Don't forget to change 'imagefile' path and fileContent variable.
private async void SaveFile()
{
try
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
if(folder != null)
{
StorageFile file = await folder.CreateFileAsync("imagefile", CreationCollisionOption.ReplaceExisting);
byte[] fileContnet = null; // This is where you set your content as byteArray
Stream fileStream = await file.OpenStreamForWriteAsync();
fileStream.Write(fileContent, 0, fileContent.Length);
fileStream.Flush();
fileStream.Close();
}
}
catch (Exception ex)
{
// Some Exception handling code
}
}

Windows Phone 8.1 Writing to File Not Working

I am writing text to a file in Windows Phone 8.1 like this:
private static async Task WriteData(String fileName, String content)
{
Byte[] data = Encoding.Unicode.GetBytes(content);
var folder = ApplicationData.Current.LocalFolder;
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
}
}
But when I read the file, it comes back empty. I have verified that there isn't some other method overwriting it by reading from the file immediately after I write to it. Am I missing something obvious here?
Maybe you can try:
public async Task SaveStreamToFile(Stream streamToSave, string fileName, CancellationToken cancelToken)
{
Byte[] buf= Encoding.Unicode.GetBytes(content);
var folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream fileStram = await file.OpenStreamForWriteAsync())
{
int bytesread = 0;
while ((bytesread = await streamToSave.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
{
await fileStram.WriteAsync(buf, 0, bytesread);
cancelToken.ThrowIfCancellationRequested();
}
}
}
I was having the same problem. I save 2 files, one with debug information, and one with application specific information (a list of routes).The debug information seems to work OK
StorageFolder local = ApplicationData.Current.LocalFolder;
var file = await local.CreateFileAsync "debug.txt",CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, sbDebugInformation.ToString());
but the CreateCollisionOption.ReplaceExisting seemed to be causing problems with the other information, and I ended up with this, after many alternate attempts
StorageFolder local = ApplicationData.Current.LocalFolder;
var json = new DataContractJsonSerializer(typeof(RouteList));
var file = await local.CreateFileAsync(filename,CreationCollisionOption.OpenIfExists);
MemoryStream stream = new MemoryStream();
json.WriteObject(stream, routes);
await FileIO.WriteBytesAsync(file, stream.ToArray());

OneDrive Downloaded *.jpeg Image File Corrupt in Windows Phone 8

I'm doing a backup of my app database to OneDrive. The database records refer to images that are stored in isolated storage. I backup those images too. The database files.
The destinations of the backup file is:
me/skydrive/my_documents/MyCompany/MyApp/MyBackup.bak
The destination of the jpg image files is
me/skydrive/my_documents/MyCompany/MyApp/MyBackup Images/*.jpg
The database restores fine, but the images don't. I've verified that the image is backed up properly on SkyDrive - I can see it and open it fine from SkyDrive. However, when I restore, the file is corrupt. Here's the code I use to restore:
dynamic cmpFolder = await oneDrive.FindFolder("MyCompany", "me/skydrive/my_documents");
dynamic appFolder = await oneDrive.FindFolder(AppName, cmpFolder.id);
string imagesFileName = Path.GetFileNameWithoutExtension(selectedFile.FileName) + " Images";
dynamic imgFolder = await oneDrive.FindFolder(imagesFileName, appFolder.id);
dynamic fileList = await oneDrive.FindFiles(imgFolder.id);
foreach (var fileData in fileList.data)
{
string fileName = fileData.name;
var file =
await wilFolder.CreateFileAsync(
Path.GetFileName(fileName), CreationCollisionOption.ReplaceExisting);
var result = await client.BackgroundDownloadAsync(selectedFile.FileID +
"/content/", new Uri(#"\shared\transfers\" + fileName, UriKind.Relative));
}
Using ISETool and viewing \shared\transfers, I can see that the file is no longer readable. It's size is about 128k, whereas the original image was much larger.
I've also tried this, which was my original code until I began seeing the problem:
var downloadResult = await client.DownloadAsync(selectedFile.FileID + "/content/");
using (Stream oneDriveStream = downloadResult.Stream)
{
oneDriveStream.Position = 0;
byte[] imageBytes = new byte[oneDriveStream.Length];
int count = oneDriveStream.Read(imageBytes, 0, imageBytes.Length);
using (var s = await file.OpenStreamForWriteAsync())
{
oneDriveStream.CopyTo(s);
// and tried this
//s.Write(imageBytes, 0, imageBytes.Length);
}
}
For reference, here's the FindFolder and FindFiles implementations:
public async Task<dynamic> FindFiles(string folderName)
{
LiveOperationResult filesResult = await client.GetAsync(folderName + "/files");
dynamic files = filesResult.Result;
return files;
}
public async Task<dynamic> FindFolder(string folderName, string parentFolder)
{
LiveOperationResult folderResult = await client.GetAsync(parentFolder + "/files?filter=folders");
dynamic folders = folderResult.Result;
foreach (var folder in folders.data)
if (folder.name == folderName)
return folder;
return null;
}
How do I successfully download *.jpg images from my OneDrive folder?
Try this for your download path instead:
var downloadResult = await client.DownloadAsync(selectedFile.FileID + "/picture?type=full");

Unable to delete a file with DeleteAsync

I'm working in VS2012, WinRT and C#.
I'm trying to delete some files after decompressing them. I'm getting an "Access is denied" error. If I stop the app and re-start it the same code works fine so it appears there is a handle still attached.
If I don't call the unZipFile method, I can delete the files.
Is there a definitive way to release a file? I've set it to null (file = null;) before the call to delete.
Here's the block of code that calls the unzip method:
StorageFile file = await CreateOutputFile(fileName, path);
MemoryStream theMemStream = new MemoryStream();
theMemStream.Write(bytes, 0, bytes.Length);
await FileIO.WriteBytesAsync(file, bytes);
await theMemStream.FlushAsync();
theMemStream.Dispose();
var result = await unZipFile(file, path);
file = null;
Here's the unZipFile method:
private async Task<string> unZipFile(StorageFile file, string path)
{
StorageFolder sf = await GetOutputFolder(path);
using (var zipStream = await file.OpenStreamForReadAsync())
{
using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
{
await zipStream.CopyToAsync(zipMemoryStream);
try
{
var archive = SharpCompress.Archive.ArchiveFactory.Open(file.Path);
foreach (var entry in archive.Entries)
{
entry.WriteTo(zipMemoryStream);
Stream fileData = entry.OpenEntryStream();
StorageFile outputFile = await sf.CreateFileAsync(entry.FilePath, CreationCollisionOption.ReplaceExisting);
using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
{
await fileData.CopyToAsync(outputFileStream);
await outputFileStream.FlushAsync();
outputFileStream.Dispose();
}
}
archive = null;
}
catch (Exception ex)
{
throw new IOException("Error writing decompressed output file: " + ex.Message);
}
await zipStream.FlushAsync();
zipStream.Dispose();
await zipMemoryStream.FlushAsync();
zipMemoryStream.Dispose();
}
}
return "success";
}
Here's the delete method. This is called for each file after decompression:
private async Task<string> deleteFile(string path, string filename)
{
StorageFolder folder = await GetOutputFolder(path);
var files = await folder.GetFilesAsync();
foreach (StorageFile file in files)
{
try
{
if (file != null)
{
if (file.Name == filename)
await file.DeleteAsync();
}
}
catch (Exception ex)
{
return ex.Message;
}
}
return "success";
}
On what file do you get the exception, the extracted files or the zip archive itself?
If the latter is the case, ArchiveFactory.Open() returns an IArchive which inherits IDisposable, so you should wrap var archive = SharpCompress.Archive.ArchiveFactory.Open(file.Path); in a using block so it gets disposed after use.

Categories