In my Android web app I am trying to use javascript (from a remote HTML file) to control the visibility of an Android WebView.
I have attempted to use the addJavascriptInterface class with no success. (see http://developer.android.com/guide/webapps/webview.html)
Essentially I would like my javascript to be the following
<script>
function this() {
Android.hideView('myWebViewID');
}
window.onload = this;
</script>
Seems like it would be easy, yet all my attempts cause my app to crash during debugging.
My latest attempt was something along these lines:
public class JavaScriptInterface {
Context mContext;
JavaScriptInterface(Context c) {
mContext = c;
}
public void hideView(View v) {
WebView webview_x = (WebView) v;
webview_x.setVisibility(View.GONE);
}
}
The problem is that you are casting the string "myWebViewID" in a WebView object.
I guess this is impossible.
To do what you want, you have to implement something like a switch that convert the string you use in JS to an ID (int) that identifies your WebView:
public class JavaScriptInterface {
private Activity mContext;
JavaScriptInterface(Activity c) {
mContext = c;
}
public void hideView(String v) {
int id = stringToId(v);
WebView webview_x = (WebView) mContext.findViewById(id);
webview_x.setVisibility(View.GONE);
}
private Integer stringToId(String str) {
if(str.equals("stringForId1") {
return R.id.webView1;
} else if(str.equals("stringForId2") {
return R.id.webView2;
} else if(...) {
....
} else {
return null;
}
}
}
This is the solution:
WebView:
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebChromeClient(new CustomWebChromeClient());
mWebView.addJavascriptInterface(new CustomJavaScriptInterface(),
"android");
mWebView.loadUrl("file:///android_asset/www/test.html");
CustomeJavascriptInterface:
final class CustomJavaScriptInterface {
public void hide() {
mHandler.post(new Runnable() {
public void run() {
mWebView.setVisibility(View.INVISIBLE);
}
});
}
}
HTML:
<div onclick="window.android.hide()">Click!</div>
You should be fine with this!
Note that you cannot access the webview and change its visibility without a handler!
Hope this helps!
Related
I am trying get data from JavaScript file in android but I cannot catch data which coming from inside method in JavaScript, I shared below JS File and data inside methods Which I want to catch in android.I listen like bottom but I cannot get data from JS
this returns message webPageOpen and WebPageClose and data(Type and Url) how can I listen it in android
playWebPageWidget:function(url, status){
var privateDataResponseMessage = {};
privateDataResponseMessage.Type =status==1? 'WebPageOpen':'WebPageClose';
privateDataResponseMessage.Url = url;
window.parent.postMessage(JSON.stringify(privateDataResponseMessage));
},
android codes
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
public WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void playWebPageWidget(String toast,String url) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
Main Class
WebView browser = ((Activity) context).findViewById(R.id.webView);
browser.getSettings().setJavaScriptEnabled(true);
browser.loadUrl( "file:///android_asset/index.html");
browser.addJavascriptInterface(new WebAppInterface(context), "");
If you're doing this in WebView, you need to set up a JavaScript interface.
Read: https://developer.android.com/guide/webapps/webview#BindingJavaScript
EDIT: If you want to show a toast from the JS thread. Do this:
context.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
});
Please try this and confirm that it works.
I have an android activity that holds the webview and I have a page that contains a local variable marks. The local variable will be increased when user got the correct answer. In the webpage, there is a button called exit which is supposed to close the webpage and go back to the activity in android, and it should carry the local variable marks back to the activity too. I want to ask how the exit button can be done in the webpage to close the page and return local variable by using Javascript and how can the activity in android receive the local variable from the webpage.
My activity in android:
private WebView webview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
try {
webview.setWebViewClient(new WebViewClient());
webview.loadUrl("file:///android_asset/index.html");
}
catch(Exception ex)
{
ex.printStackTrace();
}
setContentView(webview);
}
My exit button is a div:
<div class="exit" onclick="finish()">Exit</div>
I am going to use the finish() function to return the variable and close the webpage back to the activity in android.
function finish() {}
To notify the host application that a page has finished loading. Then Call onPageFinished()
webview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
SOURCE
you can do one thing..On click on the exit call any url like http://../getmark?marks=2 and once url load in the webview finish/ exit from webview. In the activity
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// parse the url here to get marks
}
});
Register a javascriptinterface to your webview in onCreate:
this.webview.addJavascriptInterface(new MyJSInterface(this), "Android");
Implement setCount method in your Activity:
public void setCount (int count) {
//do what ever you want with count
}
Make a new JavascriptInterface-Class:
public class MyJSInterface {
private YourActivity yourActivity = null;
public MyJSInterface (YourActivity yourActivity) {
this.yourActivity = yourActivity;
}
#JavascriptInterface
public void invoke (int count) {
this.yourActivity.setCount(count);
}
}
And in javascript:
function finish(marks) {
if (Android !== undefined) {
if (Android.invoke !== undefined) {
Android.invoke(marks);
}
}
}
I'm working on android web application.
I want to start new activity from javascript.I googled and found a code to show toast.this is it.
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
That code is working fine. but when I try to start new activity nothing happen.here is my code(sorry for bad english)
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
#JavascriptInterface
public void showToast(String toast) {
Intent showAd = new Intent(getBaseContext(), ShowAd.class);
startActivity(showAd);
}
}
Try this:
In your javascript code
<script type="text/javascript">
function moveToScreen() {
Android.moveToNextScreen();
}
</script>
In your java code:
public void moveToNextScreen(){
//Move to Next screen
Intent newintent = new Intent(FirstActivity.this, SecondIntent.class);
startActivity(newintent);
}
Add these in your onCreate
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new WebAppInterface(this), "Android");
//Load URL inside WebView
webview.loadUrl("Your html page url");
During onClick() function which has a if else statement inside it is not working properly from android webview. I have added the code below.
Kindly provide your suggestion were I am missing it.
Thanks a lot.
function exampleCall(message) {
if(navigator.userAgent.match(/Android/i)) {
androidexampleCall(message);
}
if(navigator.userAgent.match(/iPhone|iPad|iPod/i)){
iOSexampleCall(message);
}
}
JS call:
<div onclick="javascript:exampleCall('GameOn');">.... </div>
I guess the call that is not working is androidexampleCall(message).
Define a interface and add it to the webview on your activity, like:
Webview wv;
//...
wv.addJavascriptInterface(new myJavaScriptInterface(), "CallToAnAndroidFunction");
//...
public class myJavaScriptInterface {
#JavascriptInterface
public void androidexampleCall(String message);{
//code
}
}
On your Js code you should do the call as follows:
function exampleCall(message) {
if(navigator.userAgent.match(/Android/i)) {
window.CallToAnAndroidFunction.androidexampleCall(message);
}
if(navigator.userAgent.match(/iPhone|iPad|iPod/i)){
iOSexampleCall(message);
}
}
Seems like you didn't enabled Javascript for your Webview:
webview.getSettings().setJavaScriptEnabled(true);
EDIT:
Tested your code with this Webview:
webview = (WebView)findViewById(R.id.webView1);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("http://jonathanalbrieux.com/others/testagent.html");
Button buttonReload = (Button)findViewById(R.id.button1);
buttonReload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
webview.loadUrl("http://jonathanalbrieux.com/others/testagent.html");
}
});
And this page:
<html>
<head>
</head>
<body>
<div id="clickable" onclick="test('a')">clickaqd</div>
<script>
function test(string){
if(navigator.userAgent.match(/Android/i)) {
var divClickable = document.getElementById("clickable");
divClickable.innerHTML = string;
}
}
</script>
</body>
And everything works correctly, maybe you have some problem in androidexampleCall function.
I have a website with href in it which redirected me to https
<a id="mA" href="javascript:pLogin(2)" class="login-link__link private-cab-link"><i class="icon-user"></i>Авторизация</a>
So, I can click on it by JavaScript. It works in chrome console
javascript:(function(){document.getElementById('mA').click();})()
Now I'm trying to do the same in WebView by clicking my app's button.
public class RostelecomLoginActivity extends Activity {
WebView webView;
String url;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_rostelecom_login);
Intent webIntent = getIntent();
String url = webIntent.getStringExtra("url");
webView = (WebView) findViewById(R.id.webView1);
webView.setWebViewClient(new MeWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSaveFormData(true);
webView.getSettings().setSavePassword(true);
webView.loadUrl(url);
Button buttoner = (Button) findViewById(R.id.button1);
buttoner.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
webView.loadUrl("javascript:(function(){document.getElementById('mA').click();})()");
}
});
}
}
I'm using MyWebViewClient to allow all certificates
public class MeWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}
}
The js injection doesn't work. If I click on href in WebView it works.
What can be wrong?
click() isn't implemented in android js interface, you have to use HTML DOM Event Object, like this:
webView.loadUrl("javascript:(function(){"+
"l=document.getElementById('mA');"+
"e=document.createEvent('HTMLEvents');"+
"e.initEvent('click',true,true);"+
"l.dispatchEvent(e);"+
"})()");
You'll have to add a javaScript interface to the WebView to call a JavaScript function from android code.
Try something like this:-
Button buttoner = (Button) findViewById(R.id.button1);
buttoner.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
JavascriptInterface javasriptInterface = new JavascriptInterface(RostelecomLoginActivity.this);
webView.addJavascriptInterface(javasriptInterface, "MyInterface");
webView.loadUrl("javascript:(function(){document.getElementById('mA').click();})()");
}
});