My application has a webview calling an url and basically all the stuff will be done by the website, but after the user finishes the proccess, it will send an information for the app, like success or invalid.
I want to know how to catch this return value through the webview. Is there a way to do this?
thanks.
You should use a JavascriptInterface to expose one of your Java methods to Javascript on your website.
First, create a class to act as your interface. Any methods you want to expose to Javascript need the #JavascriptInterface annotation:
class MyJavaScriptInterface{
#JavascriptInterface
public void myMethod(boolean success){
//Do something with value
}
}
Then initialize the interface on your WebView:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new MyJavaScriptInterface(), "JSInterface");
Finally, create the Javascript function to call the Java method from your website:
<script>
//Communicate with Javascript Interface
var processComplete = function(success){
//Only call if the interface exists
if(window.JSInterface){
window.JSInterface.myMethod(success);
}
};
</script>
Related
How to add an event listener to handle window message event in a WebView. I have tried this,
webView.evaluateJavascript("window.addEventListener('message', function (e) { Android.logData('HELLO')});", null);
But it is not working. Is there any way to achieve this?
After exploring I didn't find any way to get data from the website running in WebView to the app without adding any code to in the website. And finally, I decided to make the necessary changes on my website as well. And this is how I did it:
In App
Created a class
private class JsObject {
#JavascriptInterface
public void shareData(String data) {
Log.v(LOG_TAG, data);
}
}
Add an instance of the new class as Javascript Interface to the WebView with a name
ssWebView.addJavascriptInterface(new JsObject(), "Android");
This instance will be added to the window object of the WebView as Android(name, the second argument of the above function)
In Website
In the website to share data
window.Android && window.Android.shareData("This is the data from website");
Android injects a JS interface into a web view:
JavaScriptInterface javaScriptInterface = new JavaScriptInterface(this);
browser.addJavascriptInterface(javaScriptInterface, "qp");
The interface looks like this:
public class JavaScriptInterface {
private ILoadEpi iLoadEpi;
public JavaScriptInterface(ILoadEpi iLoadEpi) {
this.iLoadEpi = iLoadEpi;
}
#JavascriptInterface
public void passParameters(String fldMerchCode,
String fldMerchRefNbr,
String fldTxnAmt,
String fldTxnScAmt,
String fldDatTimeTxn,
String fldDate1,
String fldDate2
) {
Log.d("fldMerchCode", fldMerchCode);
Log.d("fldMerchRefNbr", fldMerchRefNbr);
Log.d("fldTxnAmt", fldTxnAmt);
Log.d("fldTxnScAmt", fldTxnScAmt);
Log.d("fldDatTimeTxn", fldDatTimeTxn);
Log.d("fldDate1", fldDate1);
Log.d("fldDate2", fldDate2);
iLoadEpi.loadEpi(fldMerchCode, fldMerchRefNbr, fldTxnAmt, fldTxnScAmt, fldDatTimeTxn, fldDate1, fldDate2);
}
}
How can a web app developed using TypeScript call this Android?
Or more broadly, how can a TypeScript application call an Android method?
Add a TypeScript definition for the JavaScriptInterface type that will be injected by Android. Then declare a variable with the name of the instance injected by Android, then use it as normal. In your example, the definition you need is:
interface JavaScriptInterface {
passParameters(fldMerchCode: string,
fldMerchRefNbr: string,
fldTxnAmt: string,
fldTxnScAmt: string,
fldDatTimeTxn: string,
fldDate1: string,
fldDate2: string) : void;
}
declare var qp: JavaScriptInterface;
The qp instance injected by Android will have the method passParameters available on it. The instance is created by Android with the name qp in your call to browser.addJavaScriptInterface(javaScriptInterface, "qp");. Note that, depending on how your passParameters function is used, you may need to declare the return type as any instead of void.
Here's a complete example based on the Android guide for binding JS:
In your HTML file, add:
<input type="button" value="Say hello" id ="button"/>
<script src="./generated/bundle.js"></script>
where I assume that your generated/transpiled JavaScript is located at ./generated/bundle.js, relative to the HTML file.
In your TypeScript file, add:
interface WebAppInterface {
showToast(toast: string) : any;
}
declare var android: WebAppInterface;
var button = document.getElementById('button');
button.onclick = ()=>android.showToast('Hello Android!');
Note that the linked Android example names the injected object android:
webView.addJavascriptInterface(new WebAppInterface(this), "android");
And in case the linked example changes or disappears, here is the example WebAppInterface.java:
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();
}
}
I am working on an e-learning project using SCROM APIs, but now I got stuck at one point: how to get server-side JavaScript value in my core Android activity IN WEBVIEW from scrom API?
I am trying below code:
public class MyJavaScriptInterface
{ Context mContext;
/** Instantiate the interface and set the context */
MyJavaScriptInterface(Context c) {
mContext = c;
}
/** retrieve the ids */
public void getbookmark(final String bookmarkId) {
webView.loadUrl("javascript:Android.getbookmark(BOOKMARKED_PAGE);");
//getWindow().requestFeature();
}
#SuppressWarnings("unused")
public void showHTML(String html)
{
new AlertDialog.Builder(myApp)
.setTitle("HTML")
.setMessage(html)
.setPositiveButton(android.R.string.ok, null)
.setCancelable(false)
.create()
.show();
}
}
Do I have to take the value of onpagefinished() function of WebView?
You'll want to add a javascript interface:
mWebView.addJavascriptInterface(new MyJavaScriptInterface(getApplicationContent(), "JSInterface");
Add a method in your interface you want to call and ensure you have the #JavascriptInterface annotation so Android makes it callable:
#JavascriptInterface
public void showHTML(String html)
{
new AlertDialog.Builder(myApp)
.setTitle("HTML")
.setMessage(html)
.setPositiveButton(android.R.string.ok, null)
.setCancelable(false)
.create()
.show();
}
Then follow the approach you are doing at the moment of calling a method in javascript:
webView.loadUrl("javascript:Android.getbookmark(BOOKMARKED_PAGE);");
And the javascript method would look something like:
window.Android.getbookmark = function(variable) {
var returnValue = getSomeValue(variable);
if(!window.JSInterface) {
console.error('window.JSInterface not defined - Did you inject the javascript interface in the native app?');
}
window.JSInterface.showHTML(returnValue);
};
Notice the reason we have window.JSInterface is because we added it with that name in:
mWebView.addJavascriptInterface(new MyJavaScriptInterface(getApplicationContent(), "JSInterface");
NOTE: In KitKat it is more efficient to use evaluateJavascript() than loadUrl, simplest form shown below, allow you can pass in a callback to get a return value (Demo in the sample code)
webView.evaluateJavascript("Android.getbookmark(BOOKMARKED_PAGE);", null);
There is a full JS Interface sample here which includes the new API's in KitKat: https://github.com/GoogleChrome/chromium-webview-samples
you can use javascript bridge for your requirement
you can find the source , this too
Can some help me in getting the return value of a javascript function from within android native code. The answer to this thread helped me to get the alert value of the javascript function from android java activity class but not the return value. In the following js function, if I do
echo window.localStorage["email"]
I get an alert in my java activity class. However
return window.localStorage["email"]
does nothing and I instead I get the error cannot convert from void to String for my
MyActivity.activity.sendJavascript("userEmail();")
Here is my js function:
function userEmail() {
return window.localStorage["email"];
}
Try:
function userEmail() {
var email=’’;
email=window.localStorage["email"];
return email;
}
Is there any documentation regarding the WebView JavaScript Bridge? I am looking for documentation that describes the capabilities and supported data types for methods defined within the "JavascriptInterface".
For example if I define the following:
public class JavaScriptInterface {
public int incrementNumber(int num) {
return num + 1;
}
If I call this method from within JavaScript and run it in the emulator, everything seems to work fine. If I run this on my NexusOne, the passed in "num" argument is always "0".
If I change the above to:
public class JavaScriptInterface {
public int incrementNumber(String num) {
// Leaving out try/catch
int tempNum = newRadius = Integer.parseInt(num);
return tempNum + 1;
}
... everything seems to work. So I am wondering if JavaScriptInterface method arguments should/can only be of type String?
Relevant resources:
http://developer.android.com/reference/android/webkit/WebView.html
http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
http://code.google.com/apis/maps/articles/android_v3.html
You can either require String args on the Java side or ensure that numbers are actual numbers (and not text versions of numbers - see about.com - JavaScript: Strings to Numbers) on the JavaScript side.
The only relevant official doc is here:
http://developer.android.com/guide/webapps/webview.html
But no description about the available types