Call Java function from JavaScript over Android WebView
I don't think this is the best solution to get the javascript to execute java code. See here:
If you want to expose native code to the HTML to be callable via javascript, do the following around your web view declaration:
JavaScriptInterface jsInterface = new JavaScriptInterface(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");
Declare the class JavaScriptInterface
:
public class JavaScriptInterface {
private Activity activity;
public JavaScriptInterface(Activity activity) {
this.activity = activity;
}
@JavascriptInterface
public void startVideo(String videoAddress){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(videoAddress), "video/3gpp");
activity.startActivity(intent);
}
}
I am declaring a single function for playing a video, but you can do whatever you want.
Finally you call this in the WebView
contents via simple javascript call:
<video width="320" height="240" controls="controls" poster='poster.gif'
onclick="window.JSInterface.startVideo('file:///sdcard/test.3gp');" >
Your browser does not support the video tag.
</video>
The example is taken from another answer of mine, about playing videos, but should be explaining enough.
EDIT As per @CedricSoubrie's comment: if the target version of the application is set to 17 or higher you need to add annotation @JavascriptInterface
above each method you want to export to the web view.
Calling Java method in Android from JavaScript using webview
This is very weird, I tried using this a couple of hours ago:
$(".connectToAndroid").on('click', function () {
var val = Android.helloWorld();
alert(val);
});
Then I changed it, it didn't say Android anymore,
yet I kept getting an error saying:
Uncaught ReferenceError: Android is not defined
And after a while I figured, Android.helloWorld();
must be cached somehow in my webview app or something.
So, I changed back to this:
$(".connectToAndroid").on('click', function () {
var val = Android.helloWorld();
alert(val);
});
And added this:
web.addJavascriptInterface(jsInterface, "Android");
And now it works like a charm, as it should have from the beginning if it wasn't for some cache somewhere,
Can anyone explain why this happens? Does android webview actually cache javascript code? And can I prevent this behaviour in the future somehow? Cache bothers a lot when coding/testing new stuff.
Call Java method from JavaScript and return value to JavaScript
It looks like issue with getting the String with proper Id. change your getLocalizedString
as follows:
@JavascriptInterface
public String getLocalizedString(final String stringId) {
localizedString = getResources().getString(getResources().getIdentifier(stringId,"string",getContext().getPackageName()));
Toast.makeText(getActivity(), "localizedString :: " + localizedString, Toast.LENGTH_SHORT).show();
return localizedString;
}
android Cannot run Java function from Javascript
I am not sure why, but you can fix this problem by adding a JavaScript interface prior to loading your HTML content.
jsInterface = new JavaScriptInterface(activity);
fragmentWebView.getSettings().setJavaScriptEnabled(true);
fragmentWebView.getSettings().setDomStorageEnabled(true);
fragmentWebView.addJavascriptInterface(jsInterface, "JSInterface");
fragmentWebView.loadDataWithBaseURL("file:///android_asset/", fullHtml, "text/html", "utf-8", null);
fragmentWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.loadUrl(
"javascript:var imgs = document.getElementsByTagName('img');" +
"for (var i = 0; i < imgs.length; i++) {" +
"imgs[i].src = 'file:///android_asset/rules_images_placeholder.png';" +
"imgs[i].addEventListener('click', function(e) {" +
"window.JSInterface.showToast(); " +
"});" +
"}" +
"console.log(window.JSInterface);" +
"window.JSInterface.showToast(); ");
}
});
It is possible to call a javascript function in android?
I believe you can use
WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new MyCustomChromeClient(this));
webView.getSettings().setJavaScriptEnabled(true);
webView.evaluateJavascript("globalJavascriptFunction();", null);
https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
The second argument is a callback.
[edit]
To get a value back from the javascript, you can do something like this:
webView.evaluateJavascript("globalJavascriptFunction();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String result) {
// result is the return value of globalJavascriptFunction()
// you'll have to do some testing inside here to figure out exactly how result gets sent back for your usecase
}
});
Run JavaScript in Android webview
Well I replaced:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webview.evaluateJavascript(javascript, null);
} else {
webview.loadUrl("javascript:(function(){" + javascript + "})()");
}
with
webview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView webview, String url) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webview.evaluateJavascript(javascript, null);
} else {
webview.loadUrl("javascript:(function(){" + javascript + "})()");
}
}
});
and it just WORKS!
Call Android methods from JavaScript
You can do this by adding a JavaScript Interface to your WebView and exposing specific methods to the JavaScript code running in your web view. In other words, you'll need to wrap the calls to Android's Toast class in a method you create in your activity/fragment.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView android:id="@+id/web_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = (WebView)findViewById(R.id.web_view);
webView.loadUrl("file:///android_asset/web.html");
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewJavaScriptInterface(this), "app");
}
/*
* JavaScript Interface. Web code can access methods in here
* (as long as they have the @JavascriptInterface annotation)
*/
public class WebViewJavaScriptInterface{
private Context context;
/*
* Need a reference to the context in order to sent a post message
*/
public WebViewJavaScriptInterface(Context context){
this.context = context;
}
/*
* This method can be called from Android. @JavascriptInterface
* required after SDK version 17.
*/
@JavascriptInterface
public void makeToast(String message, boolean lengthLong){
Toast.makeText(context, message, (lengthLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT)).show();
}
}
}
assets/web.html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript View</title>
<script type="text/javascript">
function showToast(){
var message = document.getElementById("message").value;
var lengthLong = document.getElementById("length").checked;
/*
Call the 'makeToast' method in the Java code.
'app' is specified in MainActivity.java when
adding the JavaScript interface.
*/
app.makeToast(message, lengthLong);
return false;
}
/*
Call the 'showToast' method when the form gets
submitted (by pressing button or return key on keyboard).
*/
window.onload = function(){
var form = document.getElementById("form");
form.onsubmit = showToast;
}
</script>
</head>
<body>
<form id="form">
Message: <input id="message" name="message" type="text"/><br />
Long: <input id="length" name="length" type="checkbox" /><br />
<input type="submit" value="Make Toast" />
</form>
</body>
</html>
Related Topics
Read CSS Property of an Element Using JavaScript
Black and White Text Based on Background Image with CSS
Delete Firebase Data Older Than 2 Hours
Best Way to Find If an Item Is in a JavaScript Array
How to Run Multiple Npm Scripts in Parallel
How to Handle Newlines in Json
Deleting Objects in JavaScript
How to Show a Running Progress Bar While Page Is Loading
Convert Xml to Json (And Back) Using JavaScript
Jspdf Can't Get Any Styling to Work
How to Match Overlapping Strings With Regex
Force Browser to Refresh CSS, JavaScript, etc
Can't Access Object Property, Even Though It Shows Up in a Console Log
Prevent Address-Bar Hiding in Mobile Browsers
How to Output Numbers With Leading Zeros in JavaScript