FileReference: Loading a Windows-locked file - windows

I'm using Flex in Flash Player 10 on Windows, using FileReference to load a file into memory, as below.
My issue is that when a file is locked by Windows, my FileReference is not giving me any feedback that the file is inaccessible--it simply never dispatches any events after my calling load().
Does anyone have insight into how to tell that Flash Player is unable to open the file?
var fileReference:FileReference = new FileReference();
private function onClick():void {
fileReference = new FileReference();
fileReference.addEventListener(Event.SELECT, onSelect);
fileReference.addEventListener(Event.COMPLETE, onComplete);
fileReference.addEventListener(Event.CANCEL, onOther);
fileReference.addEventListener(IOErrorEvent.IO_ERROR, onOther);
fileReference.addEventListener(ProgressEvent.PROGRESS, onOther);
fileReference.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onOther);
// I've tried adding all of the other declared events
// for FileReference here as well
fileReference.browse();
}
private function onSelect(event:Event):void {
trace(fileReference.name);
try {
fileReference.load();
} catch (e:Error) {
trace(e);
}
}
private function onComplete(event:Event):void {
trace(fileReference.data.length);
}
private function onOther(event:Event):void {
trace("other:" + event.toString());
}

A possible (dirty) workaround might be to wait for -let say- 10 seconds, and suppose that the file isn't available if no event has triggered then.
Using a setTimeout (and clearing it with clearTimeout in your COMPLETE and *_ERROR events handlers) might do the trick.
I'll be glad if someone could come up with a nicer solution, though.
EDIT: Of course you might want to listen to HTTP_STATUS event (waiting for a 202 answer - if I understood this documentation correctly) rather than waiting for COMPLETE or *_ERROR.

Related

Running a non-blocking, high-performance activity in nativescript/javascript

This question is about running a non-blocking, high-performance activity in nativescript that is needed for the simple task of reading and saving raw audio from the microphone by directly accessing the hardware through the native Android API. I believe I have brought the nativescript framework to the edge of its capabilities, and I need experts' help.
I'm building a WAV audio recorder in Nativescript Android. Native implementation is described here (relevant code below).
In short, this can be done by reading audio steam from an android.media.AudioRecord buffer, and then writing the buffer to a file in a separate thread, as described:
Native Android implementation
startRecording() is triggered by a button press, and starts a new Thread that runs writeAudioDataToFile():
private void startRecording() {
// ... init Recorder
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
Recording is stopped by setting isRecording to false (stopRecording() is triggered by a button press):
private void stopRecording() {
isRecording = false;
recorder.stop();
recorder.release();
recordingThread = null;
}
Reading and saving buffer is stopped if isRecording = false:
private void writeAudioDataToFile() {
// ... init file and buffer
ByteArrayOutputStream recData = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(recData);
int read = 0;
while(isRecording) {
read = recorder.read(data, 0, bufferSize);
for(int i = 0; i < bufferReadResult; i++) {
dos.writeShort(buffer[i]);
}
}
}
My Nativescript javascript implementation:
I wrote a nativescript typescript code that does the same as the native Android code above. The problem #1 I faced was that I can't run while(isRecording) because the javascript thread would be busy running inside the while loop, and would never be able to catch button clicks to run stopRecording().
I tried to solve problem #1 by using setInterval for asynchronous execution, like this:
startRecording() is triggered by a button press, and sets a time interval of 10ms that executes writeAudioDataToFile():
startRecording() {
this.audioRecord.startRecording();
this.audioBufferSavingTimer = setInterval(() => this.writeAudioDataToFile(), 10);
}
writeAudioDataToFile() callbacks are queued up every 10ms:
writeAudioDataToFile() {
let bufferReadResult = this.audioRecord.read(
this.buffer,
0,
this.minBufferSize / 4
);
for (let i = 0; i < bufferReadResult; i++) {
dos.writeShort(buffer[i]);
}
}
Recording is stopped by clearing the time interval (stopRecording() is triggered by button press):
stopRecording() {
clearInterval(this.audioBufferSavingTimer);
this.audioRecord.stop();
this.audioRecord.release();
}
Problem #2: While this works well, in many cases it makes the UI freeze for 1-10 seconds (for example after clicking a button to stop recording).
I tried to change the time interval that executes writeAudioDataToFile() from 10ms to 0ms and up to 1000ms (while having a very big buffer), but then the UI freezes were longer and, and I experienced loss in the saved data (buffered data that was not saved to the file).
I tried to offload this operation to a separate Thread by using a nativescript worker thread as described here, where startRecording() and stopRecording() are called by messages sent to the thread like this:
global.onmessage = function(msg) {
if (msg.data === 'startRecording') {
startRecording();
} else if (msg.data === 'stopRecording') {
stopRecording();
}
}
This solved the UI problem, but created problem #3: The recorder stop was not executed on time (i.e. recording stops 10 to 50 seconds after the 'stopRecording' msg.data is received by the worker thread). I tried to use different time intervals in the setInterval inside the worker thread (0ms to 1000ms) but that didn't solve the problem and even made stopRecording() be executed with greater delays.
Does anyone have an idea of how to perform such a non-blocking high-performance recording activity in nativescript/javascript?
Is there a better approach to solve problem #1 (javascript asynchronous execution) that I described above?
Thanks
I would keep the complete Java implementation in actual Java, you can do this by creating a java file in your plugin folder:
platforms/android/java, so maybe something like:
platforms/android/java/org/nativescript/AudioRecord.java
In there you can do everything threaded, so you won't be troubled by the UI being blocked. You can call the Java methods directly from NativeScript for starting and stopping the recording. When you build your project, the Java file will automatically be compiled and included.
You can generate typings from your Java class by grabbing classes.jar from the generated .aar file of your plugin ({plugin_name}.aar) and generate type declarations for it: https://docs.nativescript.org/core-concepts/android-runtime/metadata/generating-typescript-declarations
This way you have all the method/class/type information available in your editor.

UmbrellaException which contains ClassCastException when using GWTBootstrap3 Extras Summernote event handling (KeyUp Event)

I try to handle a Summernote Keyup event with this:
myEditor.addSummernoteKeyUpHandler(new SummernoteKeyUpHandler() {
#Override
public void onSummernoteKeyUp(final SummernoteKeyUpEvent event) {
// TODO Auto-generated method stub
log.fine("hello");
}
});
I get a UmbrellaException which is IMHO a class cast exception.
This is the call stack
I identified the following spot where te cast failes:
#HasNoSideEffects
static native boolean canCast(Object src, JavaScriptObject dstId) /*-{
if (#com.google.gwt.lang.Cast::instanceOfString(*)(src)) {
return !!#com.google.gwt.lang.Cast::stringCastMap[dstId];
} else if (src.#java.lang.Object::castableTypeMap) {
return !!src.#java.lang.Object::castableTypeMap[dstId]; //<-- this returns false!!!
} else if (#com.google.gwt.lang.Cast::instanceOfDouble(*)(src)) {
return !!#com.google.gwt.lang.Cast::doubleCastMap[dstId];
} else if (#com.google.gwt.lang.Cast::instanceOfBoolean(*)(src)) {
return !!#com.google.gwt.lang.Cast::booleanCastMap[dstId];
}
return false;
}-*/;
dstId contains:
Any help greatly appreciated!
I tested this with a small demo which actually works. But in my large application, I get this exception and I don't see why.
Do you have any idea whats wrong here?
Best regards
Hannes
As Andrei suggested I set the style to DETAILED. I use Eclipse as a development environment. I decided to clean build the system (which I had done before). Now the problem has simply vanished !! Furthermore, I use SDBG (see: https://sdbg.github.io/) to debug my GWT application. This works pretty well (even without -style DETAILED). Now the very very strange thing remains. I can set breakpoints for my application and they all work well, except setting a breakpoint within the event handling method. I use a logger to print some text to the console, so I see that the event handler for summernote is actually called but the debugger will not stop. I checked whether the breakpoint is listed in the tab "Breakpoints" and it is and it is checked. I don't get it. Perhaps I have to rebuild all again.
But to keep long things short:
The solution to the problem is probably to really issue a clean build and then hope for the best.

Firefox Selenium test freezes sometimes

I am using Selenium 2.46 and Firefox 31. Whenever my test gets to a point that an web-element does not exist (or an exception is thrown) my test freezes, but it does not happen when I use Chrome. Just to let you know I have already used different versions of selenium-java and Firefox. Please find the code below:
List<WebElement> divs = driverChrome.findElements(By.tagName("div"));
int i = 0;
while (true) {
boolean breakIt = true;
System.out
.println("Waiting for map to load completely, thanks for your patience.");
for (WebElement weDiv : divs) {
try {
if (weDiv.getText().equals("Loading")) {
Thread.sleep(2000);
breakIt = false;
break;
}
} catch (Exception e) {
}
}
if (breakIt) {
break;
}
driverChrome.manage().timeouts()
.implicitlyWait(5, TimeUnit.SECONDS);
divs = driverChrome.findElements(By.tagName("div"));
}
I am using this code to wait till a map is completely loaded
The most probable reason for your test to freeze is the while(true) loop. If the text "Loading" does not show up, there still can be an (invisible) element with that text.
Anyway, I would never use a wait mechanism without timeout. And I would always try to use methods provided by the framework.
WebDriver offers explicit and implicit wait mechanisms. This one-liner could replace your whole listing (waits for up to 60s, polling every two seconds):
new WebDriverWait(driver, 60000L, 2000L).until(ExpectedConditions.invisibilityOfElementWithText(By.tagName("div"), "Loading"));
Hope it helps. If not, check out other methods of ExpectedConditions or implement your own ExpectedCondition.

Struggling to find issue with why AsyncTask is not being stopped by Handler

I am using this example:
Android - Setting a Timeout for an AsyncTask?
in the following way:
al.setOnClickListener(new OnClickListener(){
public void onClick(View w)
{
final AlogLoader loader = new AlogLoader();
loader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
if(loader.getStatus() == AsyncTask.Status.RUNNING)
{
loader.cancel(true);
}
}
}, 1);
}
});
I set it to "1" because I wanted to see if I can stop it practically before it even starts - to see if my handler is working - in reality I would probably set it to 15000 (15 seconds).
However what happens is confusing:
Running the application, causes my onPreExecute() to draw a loading screen, which doesn't ever exit, so the user just sees a loading screen perpetually.
Running it in the debugger with the breakpoint at loader.cancel(true) -> Causes the debugger to stop at that line, which is expected because its only allowed to run for 1 millisecond. However, when I hit the resume button in the debugger after that - my onPostExecute() is called... How is that possible?
Clearly, I'm very new to timing out asynctasks - after some research, I found the example above and it seemed to make the most sense to me, definitely more then
loader.get(15000, TimeUnit.MILLISECONDS);, since that blocks the UI Thread.
Any help is appreciated...even an explanation on the process..
Okay,
So I essentially solved my problem but I am still confused... Don't know if that's all good.
I was unclear on how loader.cancel(true) actually works. Based on the API level (read this question : AsyncTask.onCancelled() not being called after cancel(true)) you need to have an onCancelled() or onCancelled(params) method, or both in your AsyncTask.
I did not have this, so this explains why I saw a loading screen forever. Okay Good.
Yet, it doesn't explain how in the debugger, I managed to still call the onPostExecute(), because according to Android API's, onPostExecute is never called once cancel(true) has been called...
The answer is:
Add this to your AsyncTask-
#Override
protected void onCancelled()
{
Toast.makeText(FriendsActivity.this,"Blah- reason", Toast.LENGTH_LONG).show();
loadingScreen.dismiss();
}

Out of Range exception while accessing the files in Windows 8 Metro app

Below is the code I used to access the asset file for a metro app I am working on.
async void readFileFromDisk (string fileName, string fileType)
{
string fileContent;
StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(fileName);
using (IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read))
{
using (DataReader dataReader = new DataReader(readStream))
{
UInt32 numBytesLoaded = await dataReader.LoadAsync((UInt32)readStream.Size);
fileContent = dataReader.ReadString(numBytesLoaded);
}
}
This code is run in the handler for Loaded event for the page. I am currently getting an exception saying "Value does not fall in range". The error occurs at the first line itself, where I try to get storagefile handle from the installation folder.
On debugging, the fileName string comes out to be Null. I guess, I should be moving the code to some event which is fired at a later stage in page lifecycle, but can't seem to figure out what is the best place to do it. Suggestions??
P.S. I need to read this file before any interaction from user, as it reads the data for the level, that user will be interacting with.
Edit:
Missed a couple things.
The below function is called from the handler for loaded event.
void Game_Loaded(object sender, RoutedEventArgs e)
{
//read all level files to the strings
readFileFromDisk("//Assets/Levels/Start" + selectedLevel + ".txt", "Start");
This handler basically calls above function for different file paths, in similar manner. The string selected level is static variable, while the fileName string is created from the same.
Edit 2:
Found the issue, but solution is still far away. The return type of readFileFromDist method is causing trouble. Changed it to Task, and this part works fine, but I get "Object reference not set to an instance" error. Tried to convert Game_Loaded event handler to async too, to use await operators, but that gives me compiler error for "wrong return type".
SO, I tried removing async completely, but I guess I can't do that. There is no way to open files without using async function. So, I essentially need a way to call the readFileFromDisk function, using await, and continue with rest of the code execution once the task is completed. Something like, "IsCompleted" event for the awaited calls for the function.
Solved! Needed to use "ms:appx///Assets/filename.txt" instead of "//Assets/filename.txt".

Resources