Scan barcode in WebView Android
I am trying to start a barcode scanner when the user clicks a button in html. However, I am getting the error:
Uncaught TypeError: Object [object Object] has no method 'scanBarcode'", source: file:///android_asset/www/index.html (49)
which is called in javascript with:
function scanner(){
Android.scanBarcode();
}
Now, in a Java file, I have the following code that declares a function in public class JavaScriptInterface
Here is my file MainActivity.java
:
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 sample code I found on the internet, everything looks good to me, the only thing I had to do in the beginning was import all the required libraries and define a variable barcode
for the type string.
Any help would be greatly appreciated .. Or maybe another way to access the barcode scanner functionality from a web view.
source to share
...
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
...
public class JavaScriptInterface {
You named your interface class JavaScriptInterface, but created a new WebAppInterface to navigate to the WebView.
Edit
The above answer still holds true: you never register an interface (JavaScriptInterface) with a WebView, so you won't have access to those methods (scanBarcode).
Since you really 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 to two interfaces. Android will have all methods defined in WebAppInterface, while Scanner will have methods defined in JavaScriptInterface. Your javascript function will become
function scanner() {
Scanner.scanBarcode();
}
Edit 2
If you are targeting sdk version 17 or higher, you must also annotate the methods you want to use in javascript
public class JavaScriptInterface {
...
@JavascriptInterface
public void scanBarcode() {
...
}
}
Bonus : some unsolicited advice, use the best names. If WebAppInterface provides methods for interacting with your application data, call it DataInterface (even this is probably too general, but I don't know what data your application is using). Since JavaScriptInterface starts the scanner and closes the application, perhaps you can call it ActionInterface. Passing them to your WebView as "AppData" and "AppActions" gives you functions like AppData.getCategories()
and AppActions.closeMyActivity()
that make more logical sense.
source to share