Search code examples
androidxamarin.androidqr-codezxing

Read QR code and automatic direct to browser from result


I recently just started programming and developing app. I would appreciate if anybody can help me. I had did the QR scanner with ZXing and are able to display the result but i would like it to open the browser automatically if an URL is detected from the QR code

The following is my code for my Scanner Activity:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.Support.V7.App;
using Android.Views;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Widget;
using Android.Gms.Vision.Barcodes;
using Android.Gms.Vision;
using Android.Graphics;
using Android.Content.PM;
using Android.Support.V4.App;
using Android;
using static Android.Gms.Vision.Detector;
using Android.Util;

namespace com.xamarin.sample.splashscreen
{
    [Activity(Label = "Scanner")]
    public class Scanner : AppCompatActivity,ISurfaceHolderCallback, IProcessor
    {
        SurfaceView cameraPreview;
        TextView txtResult;
        BarcodeDetector barcodeDetector;
        CameraSource cameraSource;
        const int RequestCameraPermissionID = 1001;

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
        {
           switch(requestCode)
            {
                case RequestCameraPermissionID:
                    {
                        if (grantResults[0]==Permission.Granted)
                        {
                            if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
                            {
                                ActivityCompat.RequestPermissions(this, new string[]
                                {
                     Manifest.Permission.Camera
                                 }, RequestCameraPermissionID);
                                return;
                            }
                            try
                            {
                                cameraSource.Start(cameraPreview.Holder);
                            }
                            catch (InvalidOperationException)
                            {

                            }
                        }
                    }
                    break;
            }
        }

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Scanner);

            cameraPreview = FindViewById<SurfaceView>(Resource.Id.cameraPreview);
            txtResult = FindViewById<TextView>(Resource.Id.txtResult);

            barcodeDetector = new BarcodeDetector.Builder(this)
                .SetBarcodeFormats(BarcodeFormat.QrCode).Build();

            cameraSource = new CameraSource.Builder(this, barcodeDetector)
                .SetRequestedPreviewSize(640, 480).Build();

            cameraPreview.Holder.AddCallback(this);
            barcodeDetector.SetProcessor(this);
        }

        public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
        {

        }

        public void SurfaceCreated(ISurfaceHolder holder)
        {
          if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
                {
                ActivityCompat.RequestPermissions(this, new string[]
                {
                     Manifest.Permission.Camera
                 }, RequestCameraPermissionID);
                return;
            }
            try
            {
                cameraSource.Start(cameraPreview.Holder);
            }
            catch (InvalidOperationException)
            {

            }
        }

        public void SurfaceDestroyed(ISurfaceHolder holder)
        {
            cameraSource.Stop();
        }

        public void ReceiveDetections(Detections detections)
        {
            SparseArray qrcodes = detections.DetectedItems;
            if(qrcodes.Size()!=0)
            {
                txtResult.Post(() =>
                {
                    Vibrator vib = (Vibrator)GetSystemService(Context.VibratorService);
                    vib.Vibrate(1000);
                    txtResult.Text = ((Barcode)qrcodes.ValueAt(0)).RawValue;
                });
            }
        }

        public void Release()
        {

        }
    }`enter code here`
}`enter code here`

Solution

  • I would like it to open the browser automatically if an URL is detected from the QR code

    When you get the ZXing.Result from the QR code, you could use Patterns.WebUrl.Matcher method to confirm whether this is a URL.

    When you use Patterns.WebUrl.Matcher(result.Text).Matches() method, this regular expression pattern to match most part of RFC 3987 Internationalized URLs, aka IRIs.

    Code like this :

    private void HandleScanResult(ZXing.Result result)
        {
            string msg = "";
    
            if (result != null && !string.IsNullOrEmpty(result.Text))
                msg = "Found Barcode: " + result.Text;
            else
                msg = "Scanning Canceled!";
    
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.PutString("result", result.Text);
            resultIntent.PutExtras(bundle);
            this.SetResult(Result.Ok, resultIntent);
    
            if (Patterns.WebUrl.Matcher(result.Text).Matches())
            {
                //If this result get from the QR code is an URL, open the browse.                    
                Intent intent = new Intent();
                intent.SetAction("android.intent.action.VIEW");
                Android.Net.Uri content_url = Android.Net.Uri.Parse(result.Text);
                intent.SetData(content_url);
                StartActivity(intent);
            }
            else
            {
                this.RunOnUiThread(() => Toast.MakeText(this, msg, ToastLength.Short).Show());
            }
        }