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.

+3


source to share


1 answer


...
    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.

+1


source







All Articles