JavaFX JSBridge doesn't work after page load - javascript

I have a strange problem; JSBridge doesn't work after the page loads but it does when the button is clicked.
Test site:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body bgcolor="#A0BEC4">
<input type="button" value="PLAY" onclick="play()"><br><br>
<script>
window.onload = function() { //does not work
stb.play("hello3");
}
function play() { // work
stb.play("hello2");
}
window.addEventListener('load', (event) => {
stb.play("hello4"); //does not work
});
stb.play("hello"); //does not work
function checkJSBridge(){ // !!! WORK !!!
if (typeof (stb.play) === "function") {
stb.play("WORK");
clearTimeout(bridge_timer);
}
}
let bridge_timer = setTimeout(checkJSBridge, 1000);
</script>
</body>
</html>
My code (JavaFX 18.0.1 and JDK 18.0.1.1):
private WebEngine webEngine = webView.getEngine();
private Worker<?> engineWorker = webEngine.getLoadWorker();
private JSBridge bridge = new JSBridge();
#Override
public final void start(Stage stage) throws Exception {
engineWorker.stateProperty().addListener(new ChangeListener<Worker.State>() {
#Override
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
if (newState == State.SUCCEEDED) {
JSObject jsobj = (JSObject) webEngine.executeScript("window");
jsobj.setMember("stb", bridge);
}
}
});
}

Related

Android webview - JavaScript callback not working?

I am using a WebView to display a web-page on an android application. https://developer.android.com/guide/webapps/webview.html
After clicking a button from the HTML, I can successfully get to the Android class WebAppInterface (From the example) and display a "Toast" alert, but trying to callback to the a javacsript function defined in my web-page is not working.
This is the code of the web-page: (Android.html)
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
if (typeof Android != 'undefined')
Android.showToast(toast);
}
function ChangeColor()
{
document.body.style.background = 'pink';
}
</script>
This is the code of the MainActivity of the Android app. It loads the url and displays it.
public class MainActivity extends AppCompatActivity {
WebView m_Webview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_Webview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = m_Webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
m_Webview.setWebViewClient(new WebViewClient());
m_Webview.loadUrl("android.html");
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this,webView), "Android");
}
}
This is the WebAppInterface on the Android app:
public class WebAppInterface {
Context mContext;
WebView mView;
/** Instantiate the interface and set the context */
WebAppInterface(Context c,WebView w) {
mContext = c;
mView = w;
}
/** Show a toast from the web page */
#JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
mView.loadUrl("javascript:ChangeColor()");
}
}
The JavaScript function ChangeColor is not getting called after the toast is getting displayed.
For more reference see: https://stackoverflow.com/a/14145116/7751339
Thanks!
The solution was to use the "post" function like this:
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
// WebView Web = new WebView(mContext);
// mView.getSettings().setUserAgentString("Android WebView");
mView.post(new Runnable() {
public void run() {
mView.loadUrl("javascript:ChangeColor()");
}
});
}
Also on KitKat and forward you need to use evaluateJavascript:
mView.evaluateJavascript("ChangeColor();",null);

link html button to java activity

I'm making an Android app to my book I have an html page I want to add a button on it which is linked to this Java code
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// listeners of our two buttons
View.OnClickListener handler = new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonShareTextUrl:
shareTextUrl();
break;
}
}
};
// our buttons
findViewById(R.id.buttonShareTextUrl).setOnClickListener(handler);
}
// Method to share either text or URL.
private void shareTextUrl() {
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
share.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
// Add data to the intent, the receiving app will decide
// what to do with it.
share.putExtra(Intent.EXTRA_SUBJECT, "book");
share.putExtra(Intent.EXTRA_TEXT, "https://play.google.com/store/apps/details?id=com.sohaibm.assrar_bac");
startActivity(Intent.createChooser(share, "share with"));
}
}
so I want you to give me an HTML code of the page that contains the button linked to this activity and thank you so much
If you use WebView to show book content you can use WebViewClient:
WebViewClient mWebClient = new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.startsWith("handle:")){
// do something
return true;
}
else{
view.loadUrl(url);
}
return true;
}
};
mWebView.setWebViewClient(mWebClient);
And your link should be:
Link text
Try like this:
Html Page:
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript">
function moveToScreenTwo() {
Android.moveToNextScreen();
}
</script>
</head>
<body>
<div>
<input type="button" value="Locate" onClick="moveToScreenTwo()" />
</div>
</body>
</html>
FirstACtivity.java:
import android.webkit.JavascriptInterface;
webView = (WebView) findViewById(R.id.load_url);
webView.getSettings().setJavaScriptEnabled(true);
if (new File(url).exists()) {
webView.loadUrl(FILENAME_PREFIX + url);
Log.d("fileurl", "" + FILENAME_PREFIX + url);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
}
//Class to be injected in Web page
public class WebAppInterface {
Context mContext;
/**
* Instantiate the interface and set the context
*/
WebAppInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public void moveToNextScreen() {
Intent i = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(i);
}
}
For more Reference: Check this tutorial.

desktop notification using javascript in windows form

i am new to this and i am creating simple application in which i click a button and a notification on desktop should be displayed. i am doing this in windows form c#
the error is " NullReferenceException was unhandled
i have one button Notify in form1. i have tried this:
form1.cs
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
webBrowser1.ScriptErrorsSuppressed = true;
}
private void btnNotify_Click(object sender, EventArgs e)
{
webBrowser1.Document.InvokeScript("notifyMe");
}
private void Form1_Load(object sender, EventArgs e)
{
string CurrentDirectory = Directory.GetCurrentDirectory();
webBrowser1.Navigate(Path.Combine(CurrentDirectory,"HTMLPage1.html"));
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.ObjectForScripting = this;
code for HTMLPage1.html :
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script language="javascript" type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
if (Notification.permission !== "granted")
Notification.requestPermission();
});
function notifyMe() {
if (!Notification) {
alert('Desktop notifications not available in your browser. Try Chromium.');
return;
}
if (Notification.permission !== "granted")
Notification.requestPermission();
else {
var notification = new Notification('Notification title', {
icon: 'http://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png',
body: "Hey there! You've been notified!",
});
notification.onclick = function () {
window.open("http://stackoverflow.com/a/13328397/1269037");
};
}
}
</script>
</head>
<body>
</body>
</html>
even if i simply put alert("Hi") in notifyMe() function, nothing else. still it displays the same error.
I have tried your code.. you should use
document.attachEvent('DOMContentLoaded', function () {..
Instead of
document.addEventListener("..
That worked from here...read more about it here https://stackoverflow.com/a/1695383/4155741
you should also remove that comma at the end of .. body: "Hey there! You've been notified!", as it prevent the script from be compiled.
You have to put your html and scripts in the debug directory if they are not automatically placed. Thats where getcurrentdirectory() hits.

Pass variable from Android to JavaScript launched in WebView

I have a WebView which in the click of an Android button loads some JavaScript into the WebView.
My question is how would I go about passing an Android variable to the JavaScript when it's loaded.
My Current code to load the JavaScript into the WebView
private OnClickListener OnClick_grabit = new OnClickListener() {
public void onClick(View v) {
webView.loadUrl("javascript: function loadScript(scriptURL) {
var scriptElem = document.createElement('SCRIPT');
scriptElem.setAttribute('language', 'JavaScript');
scriptElem.setAttribute('src', scriptURL);
document.body.appendChild(scriptElem);
} loadScript('http://www.pathtojavascript/javascript.js');");
}
};
SO I need to pass something to the JavaScript initialize() from Android.
Java Class:
public class JavaScriptInterface {
Context mContext;
JavaScriptInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public String getFromAndroid() {
return "This is from android.";
}
}
Webview code :
WebView webView = (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient() {});
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
webView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
Html and javascript:
<input type="button" value="Get from android" onClick="getFromAndroid()" />
<script type="text/javascript">
var myVar = null;
function getFromAndroid() {
myVar = Android.getFromAndroid();
alert(myVar);
}
</script>
First of all you need to load the script only once (your onClick is loading it every time), then call loadUrl("javascript:initialize(" + myNumber + ");")
The correct syntax that worked for me is
StringBuilder buf=new StringBuilder("javascript:testFunction('"+bar+"','"+foo+"')");
Log.d(TAG, "returned string:"+buf.toString());
mWebView.loadUrl(buf.toString());
You need to loadUrl in your webView, I got something like this in my previous app:
webView.loadUrl("javascript:wrapJS.functionName("+value+","+value+")"+);
Add the JitPack repository to your build file
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add this to app gradle file:
dependencies {
compile 'com.github.wendux:WebViewJavascriptBridge:master-SNAPSHOT'
}
prepare your java script like this:
<!doctype html>
<html><head>
</head><body>
<p>Mehdico</p>
<script>
function setupWebViewJavascriptBridge(callback) {
var bridge=window.WebViewJavascriptBridge||window.WKWebViewJavascriptBridge
if (bridge) { return callback(bridge); }
var callbacks=window.WVJBCallbacks||window.WKWVJBCallbacks
if (callbacks) { return callbacks.push(callback); }
window.WVJBCallbacks=window.WKWVJBCallbacks = [callback];
if(window.WKWebViewJavascriptBridge){
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
}else{
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
}
setupWebViewJavascriptBridge(function(bridge) {
bridge.callHandler('sendToJava', { success:'true' }, function(response) {
})
})
</script>
</body></html>
if you want more handlers just duplicate this lines and change [jsToJava] and data part (success:true)
bridge.callHandler('sendToJava', { success:'true' }, function(response) {
})
in your xml:
<wendu.webviewjavascriptbridge.WVJBWebView
android:id="#+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
and java:
webView = findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient(new AppWebViewClients((ProgressBar) findViewById(R.id.progressBar)));
if (Build.VERSION.SDK_INT >= 21) { // for fix invalid https certification
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webView.registerHandler("sendToJava", new WVJBWebView.WVJBHandler() {
#Override
public void handler(Object data, WVJBWebView.WVJBResponseCallback callback) {
Toast.makeText(ActivityPaymentStepBank.this, data.toString(), LENGTH_SHORT).show();
Log.d("wvjsblog", data.toString());
callback.onResult(data);
}
});
webView.loadUrl("URL OF YOUR HTML FILE");

image included javascript not appear in the webView

I used webView to show javaScript,one image was included in the javaScrip,but the webView not run the image on the contrary appear a "?"image. Idonot why?
my code:
demo.html
<html>
<script language="javascript">
/* This function is invoked by the activity */
function wave() {
document.getElementById("droid").src="android_waving.png";
alert("2");
}
</script>
<body>
<!-- Calls into the javascript interface for the activity -->
<a onClick="window.demo.clickOnAndroid()"><div style="width:80px;
margin:0px auto;
padding:10px;
text-align:center;
border:2px solid #202020;" >
<img id="droid" src="android_normal.png"/><br>
Click me!
</div></a>
</body>
</html>
public class webJsDemo extends Activity {
/** Called when the activity is first created. */
private WebView mWebView;
private Handler mHandler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.wv1);
WebSettings webSettings = mWebView.getSettings();
webSettings.setSavePassword(false);
webSettings.setSaveFormData(false);
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(false);
mWebView.setWebChromeClient(new MyWebChromeClient());
mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
mWebView.loadUrl("file:///android_asset/demo.html");
}
final class DemoJavaScriptInterface {
DemoJavaScriptInterface() {
}
/**
* This is not called on the UI thread. Post a runnable to invoke
* loadUrl on the UI thread.
*/
public void clickOnAndroid() {
mHandler.post(new Runnable() {
public void run() {
mWebView.loadUrl("javascript:wave()");
}
});
}
}
/**
* Provides a hook for calling "alert" from javascript. Useful for
* debugging your javascript.
*/
final class MyWebChromeClient extends WebChromeClient {
#Override
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
// TODO Auto-generated method stub
Log.d("aa", message);
Log.d("url", url);
Log.d("result", ""+result);
result.confirm();
return super.onJsAlert(view, url, message, result);
}
}
}
i put android_normal.png and android_waving.png in the assets and drawable folder
the result
Did you try putting your image in the same location your html file is?

Categories

Resources