I have a very simple use case i.e to programmatically call a button of a web page loaded inside my webview. Below is the code
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setAppCacheEnabled(false);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
//super.onPageFinished(view, url);
switch (view.getOriginalUrl()){
case Properties.LOGIN_URL:
webView.evaluateJavascript(
"javascript:" +
"var usernameField = document.getElementById('loginUserName');" +
"usernameField.value = '" + Properties.USERNAME + "';" +
"var passwordField = document.getElementById('loginPassword');" +
"passwordField.value = '" + Properties.PASSWORD + "';", null
);
webView.evaluateJavascript(
"javascript:" +
"document.getElementById('loginButton').click();", new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
}
}
);
break;
}
}
});
view.loadUrl(Properties.LOGIN_URL);
The username and password field injection is working fine but the code to perform button click isn't working.
I have searched a lot and experimented a lot but no luck, Is this even possible?
EDIT:
The URL I'm accessing is private to our organization, is on http and not secured, not sure if it's relevant.
I have tried another public page with login fields and the same code works and the button gets clicked successfully.
Okay I found the reason. So the onPageFinished was getting called while all the DOM elements are not loaded hence the javascript was failing. For time being it to work I have added a delayed Handler with 5 sec delay and it worked. The right solution should be to check for the page to complete to load (may be use jquery to check when the document is ready).
You can handle the webview button click this way
#JavascriptInterface
public void handleClick(String id) {
startActivity(new Intent(mContext, MainActivity.class));
}
In javascript
Android.handleClick(_id);
Related
I have a webView, and I am scraping the HTML:
webView.addJavascriptInterface(new WebScraper(), "HtmlViewer");
view.loadUrl("javascript:HtmlViewer.showHTML" +
"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
And the parameter html contains the whole HTML page:
#JavascriptInterface
public void showHTML(String html) {
scrapePage(html);
}
Now the problem is, sometimes my HTML page shows an error message if the data hasnt fully loaded, or AJAX calls failed. When that happens I want to refresh the page. So i did:
if (matcher.find()) {
id = matcher.group(1);
getLecture(dom);
} else {
Log.d("errors", "looks like player didnt load try again by refreshing page");
webView.post(new Runnable() {
#Override
public void run() {
webView.reload();
}
});
}
But it doesnt look like my showHTML(String html) method is called again after refreshing. I was hoping someone could help me.
thnkas
Wait until the page has finished loading through the interface method onPageFinished (in the WebViewClient class) and then get the content of the page using the evaluateJavascript method. This way you can get the content of the site without using the JavaScriptInterface annotation
The code will look like this
webView.evaluateJavascript("<GET HTML>", new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
Log.i(TAG, "Found HTML content: " + value);
}
}
I am currently trying to display a webview in a small popup. But I would like to first load the view, then display it when properly available.
So what I tried to do was 2 functions:
public void fetchPopUp(String url, Context appContext)
{
webView = new WebView(appContext);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(url);
}
public void displayPopUp(Activity activity)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new AlertDialog.Builder(activity, android.R.style.Theme_Material_Dialog_Alert);
} else {
builder = new AlertDialog.Builder(activity);
}
builder.setView(webView);
AlertDialog dial = builder.show();
webView.addJavascriptInterface(new TCWebAppInterface(dial, webView, activity), "WAIAndroid");
webView.loadUrl("javascript:WAIAndroid.resize(document.body.getBoundingClientRect().height)");
}
As for the WAIAndroid resize:
#JavascriptInterface
public void resize(final float height)
{
activity.runOnUiThread(new Runnable()
{
#Override
public void run()
{
Log.e("JIBA", "sizes\n" + activity.getResources().getDisplayMetrics().widthPixels + "\n" + height + "\n" + activity.getResources().getDisplayMetrics().density + "\n" + activity.getResources().getDisplayMetrics().heightPixels);
});
}
The strange thing is when I call both fetchPopup and displayPopup one after the other, it's working perfectly (beside size issue which was the point of the resize).
But when I call them separately, the popup display empty and the resize method is not called.
I tried to display every objects, the webview is still the good, I tried displaying when it's finished loading, it's called properly, I tried reloading, tried to make it invisible or gone then visible again, tried to reload in javascript. Nothing changes the fact that when I call the displayPop a bit later than right after the fetchPopup method, it doesn't work. I guessed that there's an issue after the url is loaded and "onPageFinished" is called. But I can't find how to work around this.
Any help would be greatly appreciated, I'm running out of ideas!
Thanks a lot SO!
Try to move your code:
webView.addJavascriptInterface(new TCWebAppInterface(dial, webView, activity), "WAIAndroid");
to your fetchPopUp function before loadUrl, like this:
public void fetchPopUp(String url, Context appContext){
webView = new WebView(appContext);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new TCWebAppInterface(dial, webView, activity), "WAIAndroid");
webView.loadUrl(url);
}
I using WebView to show this website
http://app.wlojii.com
I want to make control panel in notification bar to play/stop music.
The problem i cant find the function that play/stop the music.
I inspected the button element and tried some variants of functions unsuccessfully (play, play(), player.play()), and i used this method to call the functions:
mWebView.loadUrl("javascript: ...")
I am not so familiar with JavaScript and web, i need some help.
Pavel
I have added a git repo with the working code https://github.com/premithk/webviewclickeventexample
The problem last time was that getElementsByClassName returns an array. So i have changed the code to
mWebview.loadUrl("javascript(function({l=document.getElementsByClassName('mejs-playpause-button');
e=document.createEvent('HTMLEvents');
e.initEvent('click',true,true);
l[0].dispatchEvent(e);})()");
Any ways the code in repo works such that there is a button (native) that will act as play/pause
Register a Javascriptinterface or use this library.
https://github.com/lzyzsd/JsBridge/blob/master/README.md
The library acts as a bridge between webview and the Java part of the app
Yes, The idea is to inject an object to the JS part and use that as a bridge to call a function inside the native part. Have updated the git repo reflecting the change. Only thing is that before we inject the event listener we have to make sure the page is fully loaded, so it might take some time. So first thing is to add the interface mWebview.addJavascriptInterface(new JSInterface(), "jsnativebridge");
Then define the class
private class JSInterface {
#JavascriptInterface
public void playPauseClicked(String string) {
Log.d("console", "" + string);
}
}
Then wait for page load and add the event listener like below
mWebview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(activity, description, Toast.LENGTH_SHORT).show();
}
public void onPageFinished(WebView view, String url) {
Log.d("console", "" + "loaded");
mWebview.loadUrl(
"javascript:(function() { " +
"var ch=document.getElementsByClassName('mejs-playpause-button');" +
"ch[0].addEventListener('click', function(){" +
" jsnativebridge.playPauseClicked('Yes');" +
"});"+
"})()"
);
}
});
You can refer the git repo, have added a working demo.
Cheers
I have a function to load on a website once its two input fields are loaded.
function setCredentials(name, key){
document.getElementById('zoneIdent').value=name;
document.getElementById('zonePwd').value=key;
GInterface.traiterEvenementValidation();
}
It is contained in a auto.html in the *root of project*/assets/www/ folder. (I tried putting it in the /res/assets/www/ folder but I get the following from AndroidStudio : Android Resource Packaging: [QuickPronote] invalid resource directory name: C:\Users\Yann\DEV\workspace\QuickPronote\res/assets
I have to use this function on this type of website : http://81.192.152.242:8001/mobile.eleve.html?FD=1. Note that the website doesn't load quickly.
I'm using the following code :
myWebView.loadUrl(String.valueOf(url));
myWebView.loadUrl("javascript:setCredentials('" + name + "','" + key + "')");
where url, name and key are strings that user has defined.
I tried it, even with dummy text, the two fields are completed and the validation action should be launched but it seems that either the function was loaded too quickly, or either it wasn't lauched at all, because once the website is fully loaded, there is neither the values apearing or an error message saying the credentials are wrong.
If your solution includes the use of external plugin-ins/libs like JQuery, tell me so.
PS: Not using PhoneGap or anything.
Here's where I got my code from in the first place.
First, make sure you've set javascript enabled on the webview,
webView.loadUrl(String.valueOf(url));
webView.getSettings().setJavaScriptEnabled(true);
then add a listener to load the name / key once the page has finished.
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.loadUrl("javascript:setCredentials('" + name + "','" + key + "')");
}
});
edit:
I think I found your problem. The lack of the javascript "setCredentials" method in the page: http://81.192.152.242:8001/mobile.professeur.html?FD=1... did you forget to add that?
when I change the above onPageFinished method to this:
myWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
myWebView.loadUrl("javascript:document.getElementById('zoneIdent').value='test name';");
}
});
the "Identifier" field is populated with "test name" on that page.
I saw the related topic but I could not get it to function.
I need to remove a search bar and a navigation dropdown from a web view I am using.
My code is below.
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url)
{
webView.loadUrl("javascript:(function() { " +
"document.getElementsById('omc-main-navigation')[0].style.display = 'none'; " +
"})()");
}
});
webView.loadUrl(links.get(arg2));
There isn't any method like document.getElementsById().
Use
document.getElementById()
instead of the
document.getElementsById() // "s" is extra here.
It should work.