I'm working with the Android WebView and trying to handle the return of a JavaScript promise from the WebView on the Java side after calling it with evaluateJavascript.
document.java
Button buttonAnnotations = findViewById(R.id.buttonAnnotations);
buttonAnnotations.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wv.evaluateJavascript("javascript:getAnnotations();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show();
}
});
}
});
index.html
async function getAnnotations() {
await pdfViewer.getAnnotations().then(result => {
return JSON.stringify(result ,null,2);
});
}
If I change the getAnnotations() function to not be async and return a string all works fine, so I'm trying to figure out how to handle this promise in the java code to get the result.
I've seen a few similar questions but none of the answers seemed to work in this case.
As I mentioned in the comment, you are returning a Promise from the async function getAnnotations
(which cannot be used directly in onReceiveValue
).
In order to "push" the result from getAnnotations
back to Android, you have to use the JavascriptInterface
:
In your Activity you can define:
@JavascriptInterface
public void onAnnotations(String result) {
Toast.makeText(WebViewActivity.this, result, Toast.LENGTH_LONG).show();
}
and register it with:
webView.addJavascriptInterface(this, "bridge");
In this case the method onAnnotations
resists within the Activity which also contains the webView
. Therefore I use "this" for the first Argument.
The "bridge" is the namespace, where you can find the function onAnnotations on the JavaScript side.
Now all you have to do, is to make the call from JavaScript to Android:
function getAnnotations() {
pdfViewer.getAnnotations().then(result => {
bridge.onAnnotations(JSON.stringify(result ,null,2));
});
}