Is it possible to add a JavaScript interface to the Android Browser the same way one can be added to the WebView Component as illustrated in this demo. My particular use case only needs JavaScript -> android so that I can send it back to the previous activity.
You can invoke methods and functions in your webview by using javascript url's, e.g.
webview.loadUrl("javascript:somemethod()");
You will, of course, need to enable javascript on your webview:
webview.getSettings().setJavaScriptEnabled(true);
This is from java to javascript. If you want to invoke java code / android API's from javascript, use addJavascriptInterface()
webview.addJavascriptInterface(new MyJSJavaBridge(), "api");
All of this is shown in the example url you posted as well.
You can do it using jsinterface.
First you need to make the browser jsinterface enabled and then you may call to Android method from the HTML of your browser.
You may , get a fair example and idea here ...
http://android-puremvc-ormlite.blogspot.com/2011/07/using-java-script-in-android-webview.html
Related
I need to load a web application inside WebView and need to click on a certain button / or perform UI automation,
Is it possible to do that?
It is part of the android application, not testing.
I don't recommand using Selenium, but instead use Javascript events or JQuery.
For example you can add javascript to a webview.
Add javascript into WebView
And then you can use JQuery user interface like this:
$( document ).ready(function() {
$("#button-id").click();
});
I received a warning from Google Play Console that refers me to this page because I used JavaScript Interface in my app and suggest two options to solve the problem .
Option 1 tells :
Ensure that there are no objects added to the JavaScript interface of
any WebView that loads untrusted web content. You can do this in two
ways:
Ensure that no objects are ever added to the JavaScript interface
via calls to addJavascriptInterface.
Remove objects from the JavaScript interface in shouldInterceptRequest
via removeJavascriptInterface before untrusted content is loaded by
the WebView.
but I can't understand what google exactly says specially on :
Remove objects from the JavaScript interface in shouldInterceptRequest
via removeJavascriptInterface before untrusted content is loaded by
the WebView
can someone tell me more explanation ?
You can resolve this issue in following ways:
If your website supports HTTPS, use "https://" prefix in loadUrl method.
You can set android:usesCleartextTraffic to false in your Manifest or set a Network Security Config that disallows HTTP traffic. It also means that your website should run on HTTPS.
Now, coming to your question about "Remove objects from the JavaScript interface in shouldInterceptRequest via removeJavascriptInterface before untrusted content is loaded by the WebView" : It mean that your app should remove (or disable) JavaScriptInterface whenever there is any non HTTPS URL is loaded within the WebView.
After doing any of these, you need to update APK on Play Console.
Conclusion is that if you want to use JavaScriptInterface, better use HTTPS on your website. If you use HTTP, JavaScriptInterface won't be allowed by Google Play.
I faced the same problem, and have not been able to figure this out, either. What worked for me, documented in How to address "Remediation for JavaScript Interface Injection Vulnerability"?, was to use WebView.evaluateJavascript. Alas, that is not a full replacement for all use cases of JavascriptInterface, but maybe it's sufficient for your purposes.
I just release an update without doing something special and warning disappeared BUT not sure it will came back again or not
Google has asked me to address https://support.google.com/faqs/answer/9095419 in my Android app, which basically means not to use the JavaScript injection mechanism for a web page loaded via HTTP.
Not using this mechanism (option 1) doesn't work for me. Setting android:usesCleartextTraffic to false also doesn't work, as the app uses non-HTTPS traffic elsewhere. So that leaves me with "you can ensure that any affected WebViews do not load any URLs with HTTP schemes via loadUrl" - which I'm happy to do, as my app only uses file:/// URLs to load content into the WebView, which should be fine security-wise. But how do I need to code the shouldOverrideUrlLoading method so that Google's checker recognizes that I'm using only file:/// URLs?
Note that the question is different from both Remediation for JavaScript Interface Injection Vulnerability (because I'm clear what is being asked) and In Android, JavaScript Interface Injection Vulnerability (because I'm not using HTTP, but file:/// URLs).
Edit: Adding my shouldOverrideUrlLoading method. (This isn't the entire method, but the salient part of it.)
#Override
public boolean shouldOverrideUrlLoading (WebView browser, String url) {
if (url.startsWith("file:///")) {
// This is my web site, so do not override; let my WebView load the page
browser.loadUrl(url);
return true;
}
// Otherwise, the link is not for a page on my site, or is an entirely different kind of URI
// (like tel:, geo: or mailto:), so launch another Activity that handles URLs
act.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
}
I have not found a way to use file:// URLs with assets in a way that satisfies Google code checker. While this would solve the issue, I'm still not clear how one might need to code it.
What I ended up doing -which solves my immediate problem- is to call a JavaScript method via the WebView.evaluateJavascript method. When called from within WebViewClient.onPageFinished the page has finished loading, so all elements are accessible. While not important for my case, this method can also return a value to the Java code. So while it's not a general replacement for a JavascriptInterface, it addresses some of its uses cases.
Is it possible to get the content of a WebView as a string?
I tried using:
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(Constants.LOGIN_URL);
HttpWebResponse response = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
But I didn't get what i wanted because the webview stores the sessions etc.
I want a method to get the data of a logged in user from a website if this is possible.
Since you need to download the content of the WebView in the context of a logged in user, you may want to try injecting JavaScript into the WebView and then having the JavaScript send code back to a C# method.
An example of something like this can be found in XLabs' Hybrid WebView (which is the example I used to call JavaScript from C# methods).
Have a look at the URL below. You will need to create a custom renderer for each platform that you support but that should just be a matter of copying and pasting from the link below.
Once you have you custom renderer all set, you can simply pull all of the HTML using a JavaScript method.
https://github.com/XLabs/Xamarin-Forms-Labs/wiki/HybridWebView
Reply back if you run into any road blocks.
How do I invoke button clicks within page content of a TWebBrowser ? I have found this code for VCL and an older version of Delphi:
WebBrowser.OleObject.Document.GetElementByID('ID HERE').Click;
I am using XE5, developing for Android and iOS so I can not use the above code.
Any help or suggestions would be much appreciated. Thanks !
For Android: It is straight forward that you may need to write a JS function in web page and than you can call the JS function using JSInterfaces.
For iOS: You may call the instance method provided in UIWebView class to call the Javascript method. For reference please see : https://developer.apple.com/library/ios/documentation/uikit/reference/UIWebView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006950-CH3-SW21