save webview html file

Gregg Homan

Member
Licensed User
Longtime User
Martin,

I figured out my problem was being caused by invoking CallSub() with 2 arguments when I should be invoking it with 3 arguments (see Code Example #1 below). I realized that you addressed this problem after discovering that there was a second page to this thread which I apologize for overlooking yesterday when I first posted my problem. I incorrectly 'assumed' that CallSub() worked identically for both the WebViewExtras library and its predecessor JSInterface library that you obsoleted in favor of WebViewExtras library.

To quickly summarize Code Example#1 & #2 below work fine; however, I still do have one remaining problem involving using LongClick which is demonstrated in Code Example #3.

Thanks,
Gregg

'Code Example #1: Save HTML code from WebView using a PageFinished subroutine <<<-Works OK
B4X:
'Activity module
Sub Process_Globals
End Sub
Sub Globals
    Dim myInterface As WebViewExtras
    Dim WebView1 As WebView
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("layoutMain")
    myInterface.addJavascriptInterface(WebView1, "B4A")
    WebView1.LoadUrl("http://www.b4x.com/android/help/jsinterface.html")
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub WebView1_PageFinished (Url As String)
    '2 Arguments fail->>> Dim jsStatement As String = "B4A.CallSub('processHTML', document.documentElement.outerHTML)" 
    Dim jsStatement As String = "B4A.CallSub('processHTML', true, document.documentElement.outerHTML)" '<<<-3 arguments work
    myInterface.executeJavascript(WebView1, jsStatement)
End Sub
Sub processHTML(html As String)
    Log(html)
End Sub

'Code Example #2: Save HTML code from WebView using MenuItem <<<-Works OK
B4X:
'Activity module
Sub Process_Globals
End Sub
Sub Globals
    Dim myInterface As WebViewExtras
    Dim WebView1 As WebView
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Activity.AddMenuItem("Save webpage", "SaveWebpage")
    Activity.LoadLayout("layoutMain")
    myInterface.addJavascriptInterface(WebView1, "B4A")
    WebView1.LoadUrl("http://www.b4x.com/android/help/jsinterface.html")
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub SaveWebpage_Click
   Dim Javascript As String = "B4A.CallSub('processHTML', true, document.documentElement.outerHTML)"
   myInterface.executeJavascript(WebView1, Javascript)
End Sub
Sub processHTML(html As String)
    Log(html)
End Sub

'Code Example #3: Save HTML code from WebView using LongClick <<<-Fails with following error message:
java.lang.Exception: Sub webview1_longclick signature does not match expected signature.
public static anywheresoftware.b4a.pc.RemoteObject b4a.savehtml.main_subs_1._webview1_longclick(anywheresoftware.b4a.pc.RemoteObject) throws java.lang.Exception
B4X:
'Activity module
Sub Process_Globals
End Sub
Sub Globals
    Dim myInterface As WebViewExtras
    Dim WebView1 As WebView
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("layoutMain")
    myInterface.addJavascriptInterface(WebView1, "B4A")
    WebView1.LoadUrl("http://www.b4x.com/android/help/jsinterface.html")
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub WebView1_LongClick (Url As String)
    Dim jsStatement As String = "B4A.CallSub('processHTML', true, document.documentElement.outerHTML)"
    myInterface.executeJavascript(WebView1, jsStatement)
End Sub
Sub processHTML(html As String)
    Log(html)
End Sub

'Save HTML code from WebView via a MenuItem
'Save HTML code from WebView via a MenuItem
'Save HTML code from WebView via a MenuItem
'Save HTML code from WebView via a MenuItem
'Code Example #2: Save HTML code from WebView using MenuItem
B4X:
'Activity module
Sub Process_Globals
End Sub
Sub Globals
    Dim myInterface As WebViewExtras
    Dim WebView1 As WebView
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Activity.AddMenuItem("Save webpage", "SaveWebpage")
    Activity.LoadLayout("layoutMain")
    myInterface.addJavascriptInterface(WebView1, "B4A")
    WebView1.LoadUrl("http://www.b4x.com/android/help/jsinterface.html")
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub SaveWebpage_Click
   Dim Javascript As String
   Javascript="B4A.CallSub('processHTML', true, document.documentElement.outerHTML)"
   myInterface.executeJavascript(WebView1, Javascript)
End Sub
Sub processHTML(html As String)
    Log(html)
End Sub
'Code Example #2: Save HTML code from WebView using MenuItem
B4X:
'Activity module
Sub Process_Globals
End Sub
Sub Globals
    Dim myInterface As WebViewExtras
    Dim WebView1 As WebView
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Activity.AddMenuItem("Save webpage", "SaveWebpage")
    Activity.LoadLayout("layoutMain")
    myInterface.addJavascriptInterface(WebView1, "B4A")
    WebView1.LoadUrl("http://www.b4x.com/android/help/jsinterface.html")
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub SaveWebpage_Click
   Dim Javascript As String
   Javascript="B4A.CallSub('processHTML', true, document.documentElement.outerHTML)"
   myInterface.executeJavascript(WebView1, Javascript)
End Sub
Sub processHTML(html As String)
    Log(html)
End Sub
 
Upvote 0

Gregg Homan

Member
Licensed User
Longtime User
Martin,
My apologies, I had brain fart regarding Code Example #3 involving LongClick. It works fine once I fix my code as shown below.
Sorry,
Gregg
B4X:
Sub WebView1_LongClick '<<<RIGHT
'Sub WebView1_LongClick (Url AsString) <<<<WRONG
   Dim jsStatement AsString = "B4A.CallSub('processHTML', true, document.documentElement.outerHTML)"
   myInterface.executeJavascript(WebView1, jsStatement)
End Sub
 
Upvote 0

Peter Simpson

Expert
Licensed User
Longtime User
Thank you for posting your solution @Gregg Homan, It works perfect when it some to saving html code and working with a website that checks for browsers(WebView).

My scenario was that I wrote an app with a feed and well over 1000 users use the app on a daily basis, it was working perfectly fine until yesterday. The data feed feed provider suddenly implemented http://www.cloudflare.com/ onto their website because they were getting DDoS attacks. What the solution from Cloud Flare does is to check to see if you are using some sort of browser and if you are the webpage then continues to load, that's where WebView came into play.

I've been using HttpJob to request and download information from the data feed supplier, but as Cloud Flares anti DDoS system is designed to make sure that only viewing through some sort of browser(WebView in B4A) would allow data through, your Code Example #1: Save HTML code from WebView using a PageFinished subroutine was the perfect solution for me.

Without your solution, I would have had to pull my app from the Play Store for sure. The only bad point is that since implementing your solution, the data feeds only work in Release, Debug(legacy) and Debug(rapid) modes in B4A. The data feeds do not work at all in Release(obfuscated) mode, maybe that's something that @Erel can answer for me as I'm completely baffled by why that is.

Anyway cheers for the post, it works a perfect for saving HTML from a WebView to a file...
 
Last edited:
Upvote 0
Top