I am trying to start the barcode scanner upon the user pressing a button in the html. However i am recieving an error:
Uncaught TypeError: Object [object Object] has no method 'scanBarcode'", source: file:///android_asset/www/index.html (49)
Which is being called in javascript with:
function scanner(){
Android.scanBarcode();
}
Now in the Java file i have the following code, which declares the function withinpublic class JavaScriptInterface
Here is my MainActivity.java
file:
public class MainActivity extends Activity {
@SuppressWarnings("deprecation")
@SuppressLint("SetJavaScriptEnabled") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
WebView myWebView = (WebView)findViewById(R.id.webView);
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
myWebView.setInitialScale(1);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setBuiltInZoomControls(false);
webSettings.setSupportZoom(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
//webView.getSettings().setJavaScriptEnabled(true);
myWebView.setWebChromeClient(new WebChromeClient());
//myWebView.setWebViewClient(new WebViewClient());
myWebView.loadUrl("file:///android_asset/www/index.html");
}
public class JavaScriptInterface {
Context mContext;
// Instantiate the interface and set the context
JavaScriptInterface(Context c) {
mContext = c;
}
// using Javascript to call the finish activity
public void closeMyActivity() {
finish();
}
public void scanBarcode() {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android");
startActivityForResult(intent, 0);
}
} //JavascriptInterface
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
//here is where you get your result
String barcode = intent.getStringExtra("SCAN_RESULT");
}
}
}
Now this is a code sample i found on the web, everything looks fine to me, the only thing i had to do initially was import all of the necessary libraries, and define the barcode
variable to be of type string.
Any help will be greatly appreciated.. Or maybe a different method of accessing the barcode scanner functionality from a web view..
...
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
...
public class JavaScriptInterface {
You've called your interface class JavaScriptInterface, but created a new WebAppInterface to pass to the WebView.
The above answer still holds true: You never register the interface (JavaScriptInterface) with your WebView, so you will not have access to those methods (scanBarcode).
Since you actually need two interfaces in your WebView, you need to add both interfaces
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
myWebView.addJavascriptInterface(new JavaScriptInterface(this), "Scanner");
In your javascript you will have two objects Android
and Scanner
which correspond with the two interfaces. Android will have all the methods defined in WebAppInterface, while Scanner will have the methods defined in JavaScriptInterface. Your javascript function becomes
function scanner() {
Scanner.scanBarcode();
}
If you are targeting sdk version 17 or above, you must also annotate the methods you want to use in your javascript
public class JavaScriptInterface {
...
@JavascriptInterface
public void scanBarcode() {
...
}
}
Bonus: A bit of unsolicited advice, use better names. If WebAppInterface provides methods for interacting with your application's data, call it DataInterface (even that is probably too generic, but I don't know what kind of data your app uses). Since JavaScriptInterface launches the scanner and closes the app, maybe you could call it ActionInterface. Passing those to your WebView as "AppData" and "AppActions" gives you functions like AppData.getCategories()
and AppActions.closeMyActivity()
which make more logical sense.