What could cause Launcher.LaunchFileAsync to fail intermittently - windows-store-apps

In my windows store app, I allow users to open up a file, it does not exist locally then app will download it and save it the local folder of the app and then try to open it using the code below.
This works intermittently, other time the call returns false.
var launcherOption = new LauncherOptions();
launcherOption.DesiredRemainingView = Windows.UI.ViewManagement.ViewSizePreference.Default;
launcherOption.DisplayApplicationPicker = userSettings.ShowApplicationPicker;
bool success;
// fileResponse.File is a StorageFile object
if (fileResponse.OpenAs == ContentOpenOption.LocalFile)
success = await Launcher.LaunchFileAsync(fileResponse.File, launcherOption);
else
success = await Launcher.LaunchUriAsync(fileResponse.WebUri, launcherOption);
Things I have checked for:
The file is not restricted by windows ( eg: I am testing with txt, jpg files, not exe, bin, bat )
My app is visible at the time this call is made
The call is made on the UI Thread by using the code below:
var launcherOption = new LauncherOptions();
launcherOption.DesiredRemainingView = Windows.UI.ViewManagement.ViewSizePreference.UseHalf;
launcherOption.DisplayApplicationPicker = userSettings.ShowApplicationPicker;
var dispatcherObject = CoreApplication.MainView.CoreWindow.Dispatcher;
if (dispatcherObject != null && dispatcherObject.HasThreadAccess == false)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
async () =>
{
if (fileResponse.OpenAs == ContentOpenOption.LocalFile)
success = await Launcher.LaunchFileAsync(fileResponse.File, launcherOption);
else
{
launcherOption.TreatAsUntrusted = true;
success = await Launcher.LaunchUriAsync(fileResponse.WebUri, launcherOption);
}
});
}
else
{
if (fileResponse.OpenAs == ContentOpenOption.LocalFile)
success = await Launcher.LaunchFileAsync(fileResponse.File, launcherOption);
else
{
launcherOption.TreatAsUntrusted = true;
success = await Launcher.LaunchUriAsync(fileResponse.WebUri, launcherOption);
}
}
if (!success)
{
content.IsContentUpdating = false;
content.ContentStatus = string.Empty;
logger.LogMessage(string.Format("Unable to open file. {0}",
content.Name), LoggingLevel.Error);
}
}
Made sure that the file is not blocked by windows by checking it's properties.
Any other ideas what I might be missing here?

Related

Flutter data.json keeps being overwritten

So I am working with Flutter but each time I Hot Restart the app it overwrites my data.json.
// reference one of the data.json
regulatorAsync(licenseText) async {
Directory dir = await getApplicationDocumentsDirectory();
File file = File('${dir.path}/data1.json');
if (!await file.exists()) {
print("File doesn't exist");
// if it doesn't exist, create it
file = await file.create();
file = await file.writeAsString(await file.readAsString());
}
if (await file.readAsString() == "") {
print("File is empty");
file = await file.writeAsString('{"newuser": true}');
}
var json = jsonDecode(await file.readAsString());
print(json);
var a = regulator(json, licenseText);
return a;
}
//reference 2
onPressed: () async {
// write data to file
var data = await rootBundle.loadString('lib/mainapp/data.json');
var js = jsonDecode(data);
js["newuser"] = false;
var js2 = jsonEncode(js);
// get the path to the document directory.
Directory tempDir = await getTemporaryDirectory();
var appDocPath = tempDir.path;
print(js2);
var file = await File('$appDocPath/data1.json').writeAsString(js2);
print(file.readAsStringSync());
Navigator.of(context).pushReplacementNamed('/AllowPerms');
},
I know for sure there are no other refrences I even changed the names of the files to data1.json. I get back {"newusers": true} while with the onPress it should have been set to false.

Move files from applicationStorage to Documents in app

I've got an app that, since 5 years now, that displays an offline map by reading from a folder embed in it ("assets").
Since Android 11, it's impossible to read from ApplicationStorage (Error #3001: File or directory access denied), so I'm trying to copy the folder from applicationStorage to "Documents".
What I did :
source = File.applicationDirectory.resolvePath("assets/maps");
destination = File.documentsDirectory.resolvePath("Documents/www");
source.addEventListener(Event.COMPLETE, onMapCopyComplete);
source.copyToAsync(destination, false);
function onMapCopyComplete(e: Event): void {
source.removeEventListener(Event.COMPLETE, onMapCopyComplete);
log("onMapCopyComplete()");
}
I've got a return onMapCopyComplete() but when I'm looking in InternalStorage/Documents of my phone I've got the folders but all are empty... None of the files were copy..
PrintScreen computer vs phone
To read the files, here's what I'm doing :
function startMapsView()
{
var indexFile:File = File.applicationStorageDirectory.resolvePath("www/index.html");
if (!indexFile.exists)
{
log("startMapsView() Index file not found, Please check www/index.html");
return;
}
// Create StageWebView
stageWebView = new StageWebView(isMobile); // Set to TRUE for System's NativeWebView, FALSE is for AIR's WebView
stageWebView.stage = stage;
stageWebView.viewPort = new Rectangle(0, iOSStatusBarHeight + headerBarHeight, deviceStageSize.width, deviceStageSize.height - (iOSStatusBarHeight + headerBarHeight + footerBarHeight));
stageWebView.addEventListener(flash.events.Event.COMPLETE, onStageWebViewLoaded);
stageWebView.addEventListener(flash.events.ErrorEvent.ERROR, onStageWebViewError);
stageWebView.addEventListener(LocationChangeEvent.LOCATION_CHANGING, onStageWebViewLocationChanging);
// Load Map URL
stageWebView.loadURL(mapsURL);
}
And mapsURL is define by :
function setMapsURL(doNotEnableButtons: Boolean = false): void {
var indexFile: File = File.documentsDirectory.resolvePath("Documents/www/index.html");
trace("indexFile url is = "+indexFile.url);
if (!indexFile.exists) {
log("setMapsURL() Index file not found, Please check www/index.html");
return;
}
var assetsDir: File;
if (!useOnlineMaps) {
assetsDir = new File(destination.resolvePath("index.html").nativePath);
} else {
assetsDir = new File(destination.resolvePath("onlineMaps.html").nativePath);
mySavedData.data.onlineMapChoosen = false;
}
mapsURL = assetsDir.url;
log("setMapsURL() " + mapsURL);
if (!doNotEnableButtons) enableMapButtons();
}

getUserMedia and mediarecorder in html

I record audio via getUserMedia and mediarecorder:
...
navigator.mediaDevices.getUserMedia(constraints).then(mediaStream => {
try {
const mediaRecorder = new MediaRecorder(mediaStream);
mediaRecorder.ondataavailable = vm.mediaDataAvailable;
mediaRecorder.start(1000);
...
When I receive the chucks in the callback, I send them to a web api via websockets, which simply writes the parts one after another to a file:
mediaDataAvailable(e) {
if (!event.data || event.data.size === 0)
{
return;
}
vm.websocket.SendBlob(e.data);
...
The file, which is created on the webserver side in the webapi (lets call it "server.webm"), does not work correct. More exactly: It plays the first n seconds (n is the time I chose for the start command), the it stops. This means, the first chunk is transferred correctly, but it seams that adding the 2nd, 3rd, ... chuck together to a file does not work. If I push the chuncks in the web page on an array and the to a file, the resulting file (lets call it "client.webm") is working the whole recording duration.
Creating file on web client side:
mediaDataAvailable(e) {
if (!event.data || event.data.size === 0)
{
return;
}
vm.chuncks.push(e.data);
...
stopCapturing() {
var blob = new Blob(this.chuncks, {type: 'audio/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'client.webm';
document.body.appendChild(a);
a.click();
I compared the files client.webm and server.webm. They are quite similar, but there are certain parts in the server.webm which are not in the client.webm.
Anybody any ideas? Server code looks like the following:
private async Task Echo( HttpContext con, WebSocket webSocket)
{
System.IO.BinaryWriter Writer = new System.IO.BinaryWriter(System.IO.File.OpenWrite(#"server.webm"));
var buffer = new byte[1024 * 4];
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
Writer.Write(buffer);
Writer.Flush();
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
Writer.Close();
}
resolved, I write all bytes of the reserved byte array to file in server code, not the count of received bytes.

CaptureElement preview not available sometimes

I have problem with initialization camera on Windows Universal Apps. This code works and never throw any exception, but i have wrapped it into dialog control. Problem is sometimes (1/10 dialog openings) i don't see preview from camera. Have you any idea how to fix that or at least check if preview is displayed?
private async Task InitCameraAsync()
{
var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
var backCam = devices.FirstOrDefault(q => q.EnclosureLocation != null && q.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
var mediaCapture = new MediaCapture();
if (backCam != null)
{
await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings()
{
VideoDeviceId = backCam.Id,
AudioDeviceId = String.Empty,
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview
});
}
else
{
await mediaCapture.InitializeAsync();
}
CameraControl.Source = mediaCapture;
SetImageEncodingProperties(); // get encoding properties to save images
await SetPreviewResolutionAsync();
await CameraControl.Source.StartPreviewAsync();
}
}
Are you sure that you are calling the function from the UI thread to access the camera for the API to run reliably?
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.core.coredispatcher.runasync.aspx

WindowsPhone MediaTranscoder with MediaStreamSource

I'm trying to create a Video with an Image using MediaTranscoder class in WindowsPhone 8.1 SDK. If I succeed I would then use it to create a video with more images.
in the code below I find an image inside the pictures library and create a MediaStreamSample from it. this works fine!
then I create a MediaStreamSource with duration of 1 (Sec) and relate it to the sample I Created before. this works fine too!
What doesn't work is the MediaTranscoder instance.
await transcoder.PrepareMediaStreamSourceTranscodeAsync(src, ras, profile);
when I call the above method I get a "Reference not set to an instance" exception. (null Reference exception)
I don't know why this happens... please help me.
StorageFolder cameraFolder = KnownFolders.CameraRoll;
IReadOnlyList<StorageFile> fileList = await cameraFolder.GetFilesAsync();
var query = fileList.Where(f => f.Name.StartsWith("JeyLapse")).ToList();
var stream = await query[0].OpenStreamForReadAsync();
MediaStreamSample sample =
await MediaStreamSample.CreateFromStreamAsync(stream.AsInputStream(), (uint)stream.Length, new TimeSpan());
MediaStreamSource src = new MediaStreamSource(new VideoStreamDescriptor(VideoEncodingProperties.CreateMpeg2()));
src.Duration = TimeSpan.FromSeconds(1);
src.SampleRequested += (sender, args) =>
{
args.Request.Sample = sample;
};
src.Starting += (sender, args) => args.Request.SetActualStartPosition(new TimeSpan());
src.SwitchStreamsRequested += (sender, args) => args.Request.GetDeferral().Complete();
MediaTranscoder transcoder = new MediaTranscoder();
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
var newFile = await KnownFolders.VideosLibrary.CreateFileAsync("tryJeylapse", CreationCollisionOption.GenerateUniqueName);
var writestr = await newFile.OpenStreamForWriteAsync();
var ras = writestr.AsRandomAccessStream();
transcoder.VideoProcessingAlgorithm = MediaVideoProcessingAlgorithm.Default;
var trans = await transcoder.PrepareMediaStreamSourceTranscodeAsync(src, ras, profile);
await trans.TranscodeAsync();