Android Question How to use JavaScript in a WebView ?

semar

Active Member
Licensed User
Longtime User
Dear all,
I'm trying to use a Javascript library (Tune.js) in a WebView using WebViewExtras.

First question: how can I include the .js files in the app, so that the .html file loads it ?

After various attempts, I load the .js scripts in a string and build the .html document "on the fly". But this also did not work.

The produced file works in a browser, but not in the WebView. I get errors like:
B4X:
Uncaught SyntaxError: Unexpected token { in https://tonejs.github.io/build/Tone.js (Line: 1)
Uncaught ReferenceError: Tone is not defined in file:/// (Line: 5)
Uncaught ReferenceError: synth is not defined in  (Line: 1)

You find the project in the attachment.

Any help would be appreciated !
Take care,
Sergio
 

Attachments

  • jsTest.zip
    87.1 KB · Views: 228

semar

Active Member
Licensed User
Longtime User
UPDATE
It works with the URL: "https://cdnjs.cloudflare.com/ajax/libs/tone/13.0.1/Tone.min.js"
In the Log appears however:
B4X:
%c * Tone.js r13-dev *  in https://cdnjs.cloudflare.com/ajax/libs/tone/13.0.1/Tone.min.js (Line: 7)

I've also changed the CallSub to:
B4X:
Dim js As String
js = "b4a.CallSub(synth.triggerAttackRelease('C4', '4n')), false"
wbx.executeJavascript(Wb,js)

And it works, however, I get in the Logs always the error:
Uncaught Error: Method not found in (Line: 1)

I wonder if I can get rid of that error message.

I've attached the updated project for your reference.
Still, I didn't figure out how to include the .js file in the App, without having to load it via URL - which is by now the only way to make it working. If I save the Tone.min.js source code in a text file, and load it with File.ReadString in a String (these commands are commented in code), it does not work and the error messages are:
B4X:
Uncaught SyntaxError: Unexpected token { in file:/// (Line: 2)
Uncaught ReferenceError: Tone is not defined in file:/// (Line: 28)
 

Attachments

  • jsTest.zip
    87.2 KB · Views: 257
Last edited:
Upvote 0

roumei

Active Member
Licensed User
You can reference local js files only if they are in the same folder as the html file. The solution is to create a html file in xui.DefaultFolder, copy the js file to this folder and then load the html file with LoadUrl. This code works in B4A:
B4X:
' Copy the js file to xui.DefaultFolder
File.Copy(File.DirAssets, "tone.js", xui.DefaultFolder, "tone.js")
    
Dim html As String = ""
html = html & "<script src=""" & "tone.js" & """></script>" & CRLF
html = html & "<button id=""play-button"">Play/Pause</button>" & CRLF
html = html & "<script>" & CRLF
html = html & File.ReadString(File.DirAssets,"music.js") & CRLF & "</script>"
    
' Write the html file to xui.DefaultFolder
File.WriteString(xui.DefaultFolder, "index.html", html)
    
' Load the html file from xui.DefaultFolder
Wb.LoadUrl(xui.FileUri(xui.DefaultFolder, "index.html"))
This approach won't work with B4I because referencing local files is not possible with the iOS webview. In this case, you have to include all the js code in one single html file.

The Uncaught ReferenceError is caused by your call of synth.triggerAttackRelease with b4a.CallSub. I'm not sure why you use b4a.CallSub there, you can simply call it directly:
B4X:
wbx.executeJavascript(Wb, "synth.triggerAttackRelease('C4', '4n')")
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
It indeed works, many thanks roumei for your great support !
I didn't know the "trick" with the xui.DefaultFolder. Again, something new learned !
I'm not sure why you use b4a.CallSub there..
May be I have misunderstood the use of the WebViewExtras library. In the library documentation states often the use of CallSub:
WebViewExtras
Add a javascript interface to webView1, methods of the interface can be accessed using javascript with the interfaceName as the javascript namespace.
The interface contains just a single overloaded method CallSub().
Where can I find an updated documentation on how to use JavaScript inside B4A ? Is the use of WebViewExtras still the way to go ? And what is that CallSub() for ?
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
Sadly it does not work with the "normal" version of Tone.js, which contains the oscillator I would like to use.
I've updated the project.
The errors are the same as before:
B4X:
Uncaught SyntaxError: Unexpected token { in file:///data/data/test.note/files/Tone.js (Line: 1)
Uncaught ReferenceError: Tone is not defined in file:///data/data/test.note/files/index.html (Line: 4)
There's something in the Tone.js that can't be loaded by WebView/WebViewExtras.. ?
 

Attachments

  • tone.zip
    91.1 KB · Views: 199
Upvote 0

semar

Active Member
Licensed User
Longtime User
I've created a complete html file with the Tone.js script inside. This html file (complete.html) works as expected in a browser (for example Firefox).
I load it using LoadUrl. Sadly it does not work inside WebView/WebViewExtras.
The errors are the same as above.
Here the updated project with the complete.html file.
Now I'm confused..

Any help anyone ?
 

Attachments

  • tone.zip
    172.4 KB · Views: 225
Upvote 0

roumei

Active Member
Licensed User
Both projects in #5 and #6 work for me on two different phones. There is sound (but I have to admit that I don't know which kind of sound to expect). I don't see the error messages you describe. There is a message when you try to call osc.play which doesn't exist, though.
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
Yes osc.play ist false - my fault - it is osc.start.
You say, both project #5 and #6 work ? Now I'm more than puzzled..
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
I've tested on a nokia android one and it indeed works. It has Android 10.
On the samsung alpha it does not work. It has Android 5.0.2
Hmmm.. May be WebView/WebViewExtras works only after a specific O.S. version ?
May I ask you, which Android version have your two different phones ?
 
Last edited:
Upvote 0

roumei

Active Member
Licensed User
Yes, it seems strange. I tested it with a Samsung A3 with Android 8 and a Motorola g8 Power with Android 10.
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
[SOLVED]
On the Galaxy Alpha I had the Android System WebView deactivated.. now it works also on it !
As usual, the problem often resides between the chair and the keyboard.. :rolleyes:
 
Upvote 0
Top