B4A Library WebViewExtras

Hi all.

WebViewExtras is my latest library.
It's a much updated version of JSInterface.

WebViewExtras exposes more of the available native Android WebView methods to your B4A application:

addJavascriptInterface(webView1 As WebView, interfaceName As String)

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().
The CallSub method signatures are:

CallSub(subName As String, callUIThread As boolean)
CallSub(subName As String, callUIThread As boolean, parameter1 As String)
CallSub(subName As String, callUIThread As boolean, parameter1 As String, parameter2 As String)
CallSub(subName As String, callUIThread As boolean, parameter1 As String, parameter2 As String, parameter3 As String)


So if you have added the interface to your webView with the interfaceName of "B4A" then you can write javascript such as:

B4X:
B4A.CallSub('MySubName', true)

The callUIThread parameter is an important update - it's not available with JSInterface.

Does the Sub called by your javascript modify your activity UI?
If the answer is yes then you need to pass boolean true as callUIThread otherwise you can pass false.
If you pass false and then the Sub tries to modify your activity UI you will get an exception.

Does your javascript require a return value from your Sub?
If the answer is yes then the Sub MUST NOT modify the activity UI.
If CallSub is excuted with callUIThread set to true then no values will be returned from your Sub to the javascript.

You will need to structure your B4A code so that Subs that return values to javascript do not modify the activity UI.

addWebChromeClient(webView1 As WebView, EventName As String)

Add a WebChromeClient to webView1.

The default B4A WebView has no WebChromeClient.
A WebChromeClient handles many things, the WebChromeClient that WebViewExtras adds to your WebView enables:

Version 1.30 of WebViewExtras requires that an additional EventName parameter is passed to the addWebChromeClient method, see this post: http://www.basic4ppc.com/forum/addi...updates/12453-webviewextras-2.html#post102448

clearCache(webView1 As WebView, includeDiskFiles As boolean)

Clear the WebView cache.
Note that the cache is per-application, so this will clear the cache for all WebViews used in an application.

boolean includeDiskFiles - If false, only the RAM cache is cleared.

executeJavascript(webView1 As WebView, javascriptStatement As String)

Executes a string of one or more javascript statements in webView1.
javascriptStatement - A string of one or more (semi-colon seperated) javascript statements.

flingScroll(webView1 As WebView, vx As Int, vy As Int)

flingScroll is a poorly documented method of the WebView.
It's included in WebViewExtras as it may be useful but i can find no documentation for it or it's parameters.

vx and vy do not seem to be pixel values - i suspect they are velocity values for the kinetic/fling scroll.

pageDown(webView1 As WebView, scrollToBottom As boolean)

Scroll the contents of webView1 down by half the page size.

scrollToBottom - If true then webView1 will be scrolled to the bottom of the page.

Returns a Boolean value to indicate the success or failure of the scroll.

pageUp(webView1 As WebView, scrollToTop As boolean)

Scroll the contents of webView1 up by half the page size.

scrollToTop - If true then webView1 will be scrolled to the top of the page.

Returns a Boolean value to indicate the success or failure of the scroll.

zoomIn(webView1 As WebView)

Perform zoom in on webView1.

Returns a Boolean value to indicate the success or failure of the zoom.

zoomOut(webView1 As WebView)

Perform zoom out on webView1.

Returns a Boolean value to indicate the success or failure of the zoom.

Up to date documentation/reference for this library can be found here: http://www.basic4ppc.com/forum/addi...updates/12453-webviewextras-3.html#post106486.

Library and demo code is attached to this post.

The demo is a bit brief - sorry but i don't have time to write demo code for all the new methods.
The demo displays two WebViews - the top WebView has a JavascriptInterface and WebChromeClient whereas the lower WebView has neither - it is the default B4A WebView.

Martin.

Edit by Erel:
There is a security issue related to AddJavascriptInterface in older versions of Android. See this link: https://www.b4x.com/android/forum/t...ascriptinterface-vulnerability.85032/#content
 

Attachments

  • WebViewExtras_v1_42.zip
    7.8 KB · Views: 7,801
Last edited by a moderator:

deboerr

New Member
I know this thread is old, but I would like to add my 2cents here. Advice in this thread from Warwound, Erel and others made my life a breeze to implement accessing localstorage from javascript in a webpage. Thanks guys. The only thing to be careful of is to not put the code in the Initialize sub. Put your code it in B4XPage_Created ... as per below. My B4A app has a webview display avionic data (alt, airspeed, heading, groundspeed etc) which is collected and collated by an ESP32 microcontroller and pushed to the mobile device.
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private WebView1 As WebView
    Dim wvx As WebViewExtras
    Dim wvs As WebViewSettings

End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    
    wvx.addWebChromeClient(WebView1, "wvx")
    wvs.setDatabaseEnabled(WebView1, True)
    wvs.setDOMStorageEnabled(WebView1, True)
    
    WebView1.LoadUrl("http://192.168.137.1:8000/")
End Sub
 

max123

Well-Known Member
Licensed User
Longtime User
Hi @deboerr , please can this help to solve my problem I've posted here ? Maybe permisson problem ?
https://www.b4x.com/android/forum/threads/download-files-from-webview-local-storage.141068/

What I need to do is click a button created by javascript and download the file that javascript pass as blog. This is done internally by threejs library, just use it to export 3D models created by code or by user, in this case it export an STL file. If I click this button on my pc or Android phone browser, it save the file in Download folder where browser store all downloads, but I cannot do the same in a B4A WebView.
 
Last edited:

deboerr

New Member
The only other change that I made to my project was to add the following 2 lines to the project manifest file. I'm not sure if this is actually needed.
B4X:
AddManifestText(<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />)
AddManifestText(<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />)
 

max123

Well-Known Member
Licensed User
Longtime User
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
I haven't seen all posts in this thread. Generally speaking you can directly access files in XUI.DefaultFolder = File.DirInternal.

Other places require the usage of SaveAs or ContentChooser or ExternalStorage.

 

max123

Well-Known Member
Licensed User
Longtime User
Many thanks Erel,

the problem for my question is that JS send a file in blob format, it do not expets user intervention and Save dialog, on normal browser it just save the file in browser downloads folder.

Anyway put a Save dialog is not a problem, but just I cannot know how to receive the file and handle it to be saved.
 
Top