Get the HTML code from loaded WebView [duplicate] - javascript

This question already has an answer here:
Read HTML content of webview widgets
(1 answer)
Closed 9 years ago.
I have something like this
final WebView w=(WebView)findViewById(R.id.webView1);
w.loadUrl("http://somepage.com");
Is there any way to get the html page that is shown in the WebView at some moment of time ?
I want to get this html page as string variable.
The point is I want to get the html code after the javascript is executed on a client side...
any guidelines ?

One way I know;
decleration javascript handler in your activity
class LoadListener{
public void processHTML(String html)
{
Log.e("result",html);
}
}
after configure your webview;
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new LoadListener(), "HTMLOUT");
than webview client;
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
#Override
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
}
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
}
});

One way to get the code is by using the HttpClient as given here. Another solution is given in the following blog.

Related

How can I get the return value of a JavaScript function called by Android?

Is it possible in Android to call a JavaScript function (which is in my WebView) and get its return value in Java?
I know I can use a JavascriptInterface (in Android), for this I need to call the interface from the js function, but I can't modify the JavaScript function...
So I would like something like below, is it possible?
JavaScript:
function hello(){
return "world";
}
Android:
String res = myWebView.loadUrl("javascript:hello()");
// res = "world"
Thank you
Yes, it is possible. I already do many javascript injection to people website before. You just need to inject your own javascript in any website.
For example
//simple javascript to pass value from javascript to native app
String javascript = "javascript:function testHello(){return Android.hello('HAI'); testHello();}"
webview.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//put your function in string and load the javascript when the page is finished load
view.loadUrl(javascript);
}
});
// 'Android' is your variable key for triggering the function ex: Android.hello(), Android.calculate()
// you can change to other name like 'APP', so in javascript be like this ex: APP.hello(), APP.calculate()
webview.addJavascriptInterface(new WebAppInterface(this), "Android");
//load website
webview.loadUrl(PageUrl);
In WebAppInterface is where you create function to detect the javascript you inject earlier
public class WebAppInterface {
Activity mContext;
public WebAppInterface(Activity c) {
mContext = c;
}
//this function will get your value from the javascript earlier.
//Android.hello('value')
#JavascriptInterface
public void hello(String value){
//you will get HAI message in here
Log.i("TAG",value);
}
}

WebView loads URL 10 times slower than phone's Chrome browser

I've been trying to figure this one out for quite a while, and yet haven't found a solution.
Inside my app I'm extracting a website's HTML through an invisible WebView component. I do not need to view the website, just get the html it loads. The website uses JavaScript to load all of its content, and therefore I need a full web renderer in order to execute that JavaScript. In its current form, I'm overriding the WebViewClient's onPageFinished method to inject JavaScript that dumps the html into a JavaScriptInterface which then processes it.
My main issue here is that when I load this URL inside my app it would take about 8 seconds, whereas loading the exact same URL in the phone's chrome browser it takes less than a second. Any suggestions as to what might be the problem?
If it could be of any help, the JavaScript that gets executed stores a cookie inside the WebView, and then tries to retrieve it, and only if it finds said cookie (which has a short expiration time) it would load the site's HTML. In this case it actually loads data formatted with JSON (about 370k characters).
Relevant WebView code:
private void initWebView(View view) {
class JSInterface{
#JavascriptInterface
public void processHTML(String scheduleJSONResponse){
if(scheduleJSONResponse.length() > 10000){
Log.d(LOG_TAG, "Finished loading JSON");
}
}
}
webView = (WebView) view.findViewById(R.id.fragment_movies_web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JSInterface(), "Android");
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d(LOG_TAG, "Page finished loading");
webView.loadUrl("javascript:window.Android.processHTML(document.getElementsByTagName('html')[0].textContent);");
}
});
webView.loadUrl(url);
}
As for why I check that the length is more than 10k characters: Sometimes onPageFinished would get called more than once, with the first call being before the JavaScript is executed, and so I get HTML containing the script to be executed which isn't what I need.
Thanks in advance for any help!
A logcat to demonstrate the issue:
08-18 22:32:23.623 26238-26238/com.michaelsvit.kolnoa I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy#1e4dc08f time:502735009
08-18 22:32:23.638 26238-26238/com.michaelsvit.kolnoa W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 26238
08-18 22:32:31.336 26238-26238/com.michaelsvit.kolnoa D/MovieGridFragment: Page finished loading
Current code after simplifying it:
private void initWebView(View view) {
class JSInterface{
#JavascriptInterface
public void processHTML(String scheduleJSONResponse){
if(scheduleJSONResponse.length() > 10000){
Log.d(LOG_TAG, "Finished loading JSON");
}
}
}
webView = (WebView) view.findViewById(R.id.fragment_movies_web_view);
webView.getSettings().setJavaScriptEnabled(true);
//webView.addJavascriptInterface(new JSInterface(), "Android");
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d(LOG_TAG, "Page finished loading");
//webView.loadUrl("javascript:window.Android.processHTML(document.getElementsByTagName('html')[0].textContent);");
}
});
}
through an invisible WebView component..
What when it is visible?
Try it!

Set TextBox value with js injection in a WebView

Using Android Studio I am trying to set the value of a textbox in a login form of a web page which is not mine.
Here's the webView i use to work on the page:
final WebView webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webView.setWebViewClient(new WebViewClient()
{
#Override
public void onPageFinished(WebView view, String url)
{
webView.loadUrl("javascript: document.getElementById('j_password').value = 'something'");
}
});
webView.loadUrl("http://sg18224.scuolanext.info/");
the problem is that when the page has finished loading instead of setting the textbox value, the whole page becomes white and it only displays the string i was trying to set as value (in this case "something").
If i include the js line in an alert like this:
webView.loadUrl("javascript: alert(document.getElementById('j_password').value = 'something')");
it works! But also displays an alert i don't want to display.
This should help you:
final String js = "javascript:document.getElementById('j_password').value='something';";
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
if (Build.VERSION.SDK_INT >= 19) {
view.evaluateJavascript(js, new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) { }
});
} else {
view.loadUrl(js);
}
}
});
I am not sure with this answer but you may try it. typically it should be the answer. Long time no interaction with javascript though.
you may try
webView.loadUrl("javascript: document.getElementById('j_password').innerHTML = 'something'");
please comment if its not working.

Android Webview : How to catch click on the given local URL

I displaying the content in the webview. Content is loaded from the server API. Content can contain following links:
Register
How can i catch click on the #register.
I can do it with some HTML parser and append onClick event, but much better and easier will be to catch URL change to #register.
Many thanks for any advice.
Edit:
I tried the following example but without the luck
browser = (WebView) view.findViewById(R.id.intro_browser);
// Set Chrome instead of the standard WebView
browser.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
Logger.d("TEST");
return true;
}
#Override
public void onLoadResource(WebView view, String url) {
Logger.d("URL IS:");
Logger.d(url);
if (url.startsWith("app://")) {
}
}
});
browser.getSettings().setJavaScriptEnabled(true);
browser.addJavascriptInterface(new WebViewJavaScriptInterface(getContext()),
Constants.Welcome.JAVASCRIPT_NAMESPACE);
//browser.getSettings().setAllowFileAccessFromFileURLs(true);
//browser.getSettings().setAllowUniversalAccessFromFileURLs(true);
browser.loadData(htmlContent, Constants.Welcome.MIME_TYPE, Constants.Welcome.ENCODING);
You need to create custom WebViewClient:
public class CustomWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
boolean result = false;
if (Objects.equal(url, "#register")) {
result = true;
//Do what you want here
}
return result;
}
}
and then you need to give it to WebView:
webView.setWebViewClient(new CustomWebViewClient());
returning true in shouldOverrideUrlLoading means that you handled the Url while returning false means that WebView should handle it.
Add an intent filter in your manifest so that links starting with "yourapp://" or something similar will launch your app.
If you are generating the web content, then generate links for your app.
Register
If you are not generating the content, then use webview.load("javascript:// code to replace register links to yourapp://").

shouldoverrideurlloading not called Webview Android

First of all , this post may ,look like a Possible Duplicate of other question, but I have go through many questions but found them not helpful.
Now My problem is that I am loading an URL in my Webview and then I want to Trace URL on each event on webview so I have set up WebviewClient for Webview and overridden shouldoverrideurlloading method, but after first Event , shouldoverrideurlloading not getting called. (worked first time)
Here is the Code I have used :
wvSecurity = (WebView) findViewById(R.id.wvSecurity);
wvSecurity.getSettings().setJavaScriptEnabled(true);
wvSecurity.getSettings().setAllowContentAccess(true);
wvSecurity.getSettings().setAllowUniversalAccessFromFileURLs(true);
wvSecurity.getSettings().setBuiltInZoomControls(false);
wvSecurity.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
wvSecurity.getSettings().setLoadWithOverviewMode(true);
wvSecurity.getSettings().setDomStorageEnabled(true);
wvSecurity.loadUrl("URL");
wvSecurity.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view,
final String urlStr) {
Log.i("URL", "::" + urlStr);
return false;
}
}
EDIT ::
Ok, The URL which I want to Trace uses POST method , Now my question is How can I trace POST URL and its data. And one thing , I dont have access to Webpage coming in so I simply cant go for GET method. Please Help !!!
I guess this method gets called when a hyperlink is tapped from page or some redirection happens. So make sure this thing.
I think you need to pass the url in place on "URL" so this will solve your problem.
wvSecurity = (WebView) findViewById(R.id.wvSecurity);
wvSecurity.getSettings().setJavaScriptEnabled(true);
wvSecurity.getSettings().setAllowContentAccess(true);
wvSecurity.getSettings().setAllowUniversalAccessFromFileURLs(true);
wvSecurity.getSettings().setBuiltInZoomControls(false);
wvSecurity.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
wvSecurity.getSettings().setLoadWithOverviewMode(true);
wvSecurity.getSettings().setDomStorageEnabled(true);
wvSecurity.loadUrl("http://www.google.com");
wvSecurity.setWebViewClient(new HelloWebViewClient());
private class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
System.out.println("URL :: " + url);
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, final String url) {
}
}

Categories