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.b4x.com/forum/additional-libraries-official-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.b4x.com/forum/additional-libraries-official-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
- v2.20 is attached. This is the latest version.
 

Attachments

  • WebViewExtras_v1_42.zip
    7.8 KB · Views: 9,051
  • v2.20.zip
    41.1 KB · Views: 404
Last edited by a moderator:

ivan.tellez

Active Member
Licensed User
Longtime User
Error present

Well, there is an error in the log:


B4X:
Uncaught TypeError: Object [object Object] has no method 'CallSub' in null (Line: 1)


Strange thing, tested in other 3 devices and works fine, without the error.


Sample code:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   MyWebViewExtras.addJavascriptInterface(WebView1,"B4A")
End Sub


Sub Webview1_PageFinished (Url As String)
   sJavascript = "B4A.CallSub('Show_Status',true, 'NewCaptcha', 'TEST');"
   MyWebViewExtras.executeJavascript(WebView1,sJavascript)
End Sub


Thanks for the help
 
Last edited:

warwound

Expert
Licensed User
Longtime User
It's a security feature introduced with android 4.2!

Have a look here: WebView | Android Developers:
For applications targeted to API level JELLY_BEAN_MR1 and above, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript. For applications targeted to API level JELLY_BEAN or below, all public methods (including the inherited ones) can be accessed

I've updated WebViewExtras - each of the various CallSub methods now has the @JavascriptInterface annotation - and attached it to this post.
Can you give it a test - on 4.2 and ideally some older devices too - and post with your results?

I'll then 'properly' upload it as an update.

Thanks.

Martin.
 
Last edited:

ivan.tellez

Active Member
Licensed User
Longtime User
Great Work

Thanks for this update, I tested in the Galaxy S4 with Android 4.2.2 and now works.

Tested also in Galaxy S2 with Android 4.1.2 and works too.


Update:

Tested in some older devices with Android 2.3.7 and worked just fine

Thanks

:sign0098:
 
Last edited:

warwound

Expert
Licensed User
Longtime User
WebViewExtras updated to version 1.40


Version 1.40 is attached to the first post in this thread.

Martin.
 

biometrics

Active Member
Licensed User
Longtime User
We have a webview displaying HTML5 which includes a video. We are using the HTML5 video atttribute "autoplay" which works on Windows but not on Android. There are Javascript workarounds to start video playing using the .play() function but it's not working for us.

Here's an example of what we tried: http://stackoverflow.com/questions/11758651/autostart-html5-video-using-android-4-browser

Is there a workaround using WebViewExtra using the above Javascript solution?
 

enrico

Active Member
Licensed User
Longtime User
I'm trying with various devices to use webviewextras (addWebChromeClient) to display youtube videos that don't work with webview, but I don't see any difference and youtube videos don't work. Should they ?
 

warwound

Expert
Licensed User
Longtime User
Looks like video playback in a WebView is still problematic...
Have a look through some of these links:

Lots of problems and no solution that's guaranteed to work 100%.
Generally the solutions use a custom WebChromeClient that hides the WebView and shows the VideoView to be used to display the video.
But Android API levels prior to 11 use the VideoView class to display the video and API level 11 onwards use the HTML5VideoFullScreen class.
The HTML5VideoFullScreen class doesn't expose the required methods to enable it to be easily handled.
The WebChromeClient must be able to listen for the video ending and then release the class being used to display the video, otherwise subsequent attempts to play video will fail.

What versions of the Android API are you wanting your application to support?
If Honeycomb and later is all that's required then you might find that adding the existing WebChromeClient as you have already tried and then enabling hardware acceleration in the manifest is all that's required.
You'd just need to add this line to your manifest to try that:
B4X:
SetApplicationAttribute(android:hardwareAccelerated, "true")

Martin.
 

qsrtech

Active Member
Licensed User
Longtime User
HI is it possible to use this library to grab the html source from the built in browser/chrome? For example, if a user is browsing a webpage, they can then pull down their notifications and choose mine which would grab the html source and process it for specific task. Unfortunately the share via only provides the url, I can use that however it requires re-downloading the page as well there could be user/password issues.
 

warwound

Expert
Licensed User
Longtime User
HI is it possible to use this library to grab the html source from the built in browser/chrome? For example, if a user is browsing a webpage, they can then pull down their notifications and choose mine which would grab the html source and process it for specific task. Unfortunately the share via only provides the url, I can use that however it requires re-downloading the page as well there could be user/password issues.

No way!
That'd be a massive security hole if it was possible.

Imagine your app being able to grab the browser content while the user is doing some online banking or similar!
You can get the HTML from a loaded WebView but not from a browser.

Martin.
 

John Woodsmall

Active Member
Licensed User
Longtime User
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.b4x.com/forum/additional-libraries-official-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.b4x.com/forum/additional-libraries-official-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.
 

Swissmade

Well-Known Member
Licensed User
Longtime User
Hi Guys,

Any idea how do in B4J.
Like the options of this library too make thinks more easy.
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
I don't think that's possible. I think B4J would rely on an entirely different web browser, since the webview is for android.
 

warwound

Expert
Licensed User
Longtime User
I've not got any experience of using the b4j WebView so can't help on this.

Martin.
 

andrewj

Active Member
Licensed User
Longtime User
Hi Martin,
I'm having problems getting the GeolocationPermissionsRequest to fire. My code which sets the chrome client is as follows:

B4X:
wveWeb(i).addWebChromeClient(wbvWeb(i), "Geo")

My app uses an array of FlingableWebViews and WebViewExtras, but this works fine for other purposes.

The handler starts as follows:

B4X:
Sub Geo_GeolocationPermissionsRequest As Int
Try
    Dim BD As BetterDialogs
    Log("GeolocationPermissionsRequest")

However even with the same page as in your sample, the event doesn't fire.

Any ideas?
Thanks
Andrew
 

warwound

Expert
Licensed User
Longtime User
@andrewj

What device and version of android is this on?

Each new version of android seems to break existing WebView stuff with more and more paranoid permissions.

Martin.
 

warwound

Expert
Licensed User
Longtime User
OK i'll take a look a bit later, and also answer your post in the other thread.

Probably be best to create a FlingableWebView with clipboard selection and geolocation all built in...

Martin.
 

andrewj

Active Member
Licensed User
Longtime User
Thanks Martin. I like the idea of an updated FlingableWebView with everything built in!

Andrew
 

warwound

Expert
Licensed User
Longtime User
I've started to create the new 'hybrid' selectable and flingable WebView and found some info: http://android-ed.blogspot.co.uk/2012/10/copy-text-in-webview-in-android-23-and.html?m=1.

So with android API 11 and newer the WebView has clipboard functionality built in and enabled by default.
Also with API 11 and newer the android ClipboardManager class has changed.
Android API 10 and older: http://developer.android.com/reference/android/text/ClipboardManager.html.
Android API 11 and newer: http://developer.android.com/reference/android/content/ClipboardManager.html.

So before i continue and attempt to create something that is compatible with all android API versions i wanted to ask if you need to support these older versions of the android API?

If you only need to support android API 11 and newer that makes things easier in theory.
Though i wonder why if you're using a device with android 4.1.2, why your WebView has no default clipboard functionality?
Maybe you're compiling your b4a project with an android version older than 11?
If that's the case and you compile with an android version of 11 or newer do you see built in clipboard functionality?

Martin.
 
Top