从Android Web视图启动QR扫描程序并使用Xamarin返回扫描结果

时间:2016-10-27 09:31:14

标签: c# android xamarin android-webview zxing

我有这个Xamarin应用程序,当单击按钮时启动QR扫描仪。此按钮单击在Javascript中处理。单击该按钮时,将调用C#代码。这应该启动QR扫描仪,一旦扫描了值,扫描的值就会返回到Javascript函数。但是,只要单击扫描QR码的按钮,Web视图应用就会进入后台,但不会启动相机来扫描QR码。

 public class QRScannerJSInterface : Java.Lang.Object
    {
        QRScanner qrScanner;
        WebView webView;

        public QRScannerJSInterface(WebView webView)
        {
            this.webView = webView;
            qrScanner = new QRScanner();
        }

        [Export]
        [JavascriptInterface]
        public void ScanQR()
        {
            String result = qrScanner.ScanQR();
            var js = string.Format("getQRValue('{0}');", result);
            webView.LoadUrl("javascript:" + js);
            //call the Javascript method here with "result" as its parameter to get the scanned value
        }

以下是主要活动如何调用此类。

        webView = FindViewById<WebView>(Resource.Id.webView);
        webView.Settings.JavaScriptEnabled = true;
        webView.Settings.AllowFileAccessFromFileURLs = true;
        webView.Settings.AllowUniversalAccessFromFileURLs = true;
        webView.Settings.AllowFileAccess = true;
        webView.AddJavascriptInterface(new QRScannerJSInterface(webView),"CSharpQRInterface");

以下是QRScanner代码。

class QRScanner
    {
        MobileBarcodeScanner scanner;

        public QRScanner()
        {
            scanner = new MobileBarcodeScanner();
        }

        public String ScanQR()
        {
            scanner.UseCustomOverlay = false;
            scanner.TopText = "Scanning for barcode";
            Task<ZXing.Result> result = scanner.Scan();
            return result.ToString();
        }
    }

我在这里做错了什么?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

以下是有效的解决方案。请注意扫描程序异步扫描更改。在将Task添加到js文件之前,需要等待结果。

Asset scannerPage.html

<html>
<head>
    <title></title>

    <script type='text/javascript'>

        function getQRValue(result) {
    };

        function scan() {
            CSharpQRInterface.ScanQR();
        };


    </script>

</head>
<body style="background-color:powderblue;">
    <button type="button" onclick="scan()">Click Me!</button>
</body>
</html>

MainActivity

public class MainActivity : Activity
    {
        WebView webView;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            MobileBarcodeScanner.Initialize(Application);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            webView = FindViewById<WebView>(Resource.Id.webView);
            webView.Settings.JavaScriptEnabled = true;
            webView.Settings.AllowFileAccessFromFileURLs = true;
            webView.Settings.AllowUniversalAccessFromFileURLs = true;
            webView.Settings.AllowFileAccess = true;
            webView.AddJavascriptInterface(new QRScannerJSInterface(webView), "CSharpQRInterface");
            webView.LoadUrl("file:///android_asset/scannerPage.html");

        }

扫描仪界面

public class QRScannerJSInterface : Java.Lang.Object
    {
        QRScanner qrScanner;
        WebView webView;

        public QRScannerJSInterface(WebView webView)
        {
            this.webView = webView;
            qrScanner = new QRScanner();
        }

        [Export("ScanQR")]
        public void ScanQR()
        {
            qrScanner.ScanQR()
                .ContinueWith((t) =>
                {
                    //var js = string.Format("getQRValue('{0}');", t.Result);
                    //webView.LoadUrl("javascript:" + js);
                    //call the Javascript method here with "result" as its parameter to get the scanned value
                    if (t.Status == TaskStatus.RanToCompletion)
                        webView.LoadUrl(@"javascript:getQRValue('" + t.Result + "')");
                });
        }
    }

扫描仪课程

class QRScanner
    {
        MobileBarcodeScanner scanner;

        public QRScanner()
        {
            scanner = new MobileBarcodeScanner();
        }

        public async Task<string> ScanQR()
        {
            scanner.UseCustomOverlay = false;
            scanner.TopText = "Scanning for barcode";
            var result = await scanner.Scan();
            return result.ToString();
        }
    }