Xamarin.Android - QR Code Reader By Mobile Camera

Introduction
 
Today, I shall show you how to create a QR Code Reader app in Xamarin, that uses a mobile camera.
 
The Prerequisites
  • Android Support Library v7 AppCompat
  • Xamarin Android Support v4
  • Google Play Services - Vision 
The steps given below are required to be followed in order to create a QR code reader app by a mobile camera in Xamarin.Android, using Visual Studio.
 
Step 1 - Create Android Project
 
Create your Android solution in Visual Studio or Xamarin Studio. Select Android and from the list, choose Android Blank App. Give it a name, like QrReaderByCamera.
 
(ProjectName: QrReaderByCamera)
 
Step 2 - Add Android.Support.v7.AppCompat Library
 
First of all, in References, add a reference to Android.Support.v7.AppCompat using NuGet Package Manager, as shown below.
 
 
Step 3 - Add Xamarin Android Support v4
 
Similarly, install Xamarin Android Support v4 Library.
 
Step 4 - Add Xamarin Google Play Services - Vision
 
Next in References, add another reference to Xamarin GooglePlayServices Vision using NuGet Package Manager, as shown below.
 
 
 
Step 5 - Layout
 
Open Solution Explorer-> Project Name-> Resources-> Layout-> Main.axml and add the following code. The layout will have a SurfaceView in order to display the preview frames captured by the camera. I also added a TextView to display the contents of the QR Code.
 
(FileName: Main.axml)
 
XML Code
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent">  
  5.     <SurfaceView  
  6.         android:id="@+id/cameraView"  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="480dp"  
  9.         android:layout_centerInParent="true" />  
  10.     <TextView  
  11.         android:layout_centerInParent="true"  
  12.         android:gravity="center_horizontal"  
  13.         android:id="@+id/txtResult"  
  14.         android:layout_below="@+id/cameraView"  
  15.         android:layout_width="match_parent"  
  16.         android:layout_height="wrap_content"  
  17.         android:text="Please focus Camera to QR Code"  
  18.         android:textSize="20sp"  
  19.         android:layout_marginTop="20dp" />  
  20. </RelativeLayout>  
Step 6 - Main Activity Class
 
Now, go to Solution Explorer-> Project Name-> MainActivity and add the following code with appropriate namespaces.
 
(FileName: MainActivity)
 
C# Code
  1. using Android;  
  2. using Android.App;  
  3. using Android.Content;  
  4. using Android.Content.PM;  
  5. using Android.Gms.Vision;  
  6. using Android.Gms.Vision.Barcodes;  
  7. using Android.Graphics;  
  8. using Android.OS;  
  9. using Android.Runtime;  
  10. using Android.Support.V4.App;  
  11. using Android.Support.V7.App;  
  12. using Android.Util;  
  13. using Android.Views;  
  14. using Android.Widget;  
  15. using System;  
  16. using static Android.Gms.Vision.Detector;  
  17. namespace QrReaderByCamera  
  18. {  
  19.     [Activity(Label = "QrReaderByCamera", MainLauncher = true , Theme ="@style/Theme.AppCompat.Light.NoActionBar")]  
  20.     public class MainActivity : AppCompatActivity , ISurfaceHolderCallback, IProcessor  
  21.     {  
  22.         SurfaceView surfaceView;  
  23.         TextView txtResult;  
  24.         BarcodeDetector barcodeDetector;  
  25.         CameraSource cameraSource;  
  26.         const int RequestCameraPermisionID = 1001;  
  27.         public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)  
  28.         {  
  29.             switch (requestCode)  
  30.             {  
  31.                 case RequestCameraPermisionID:  
  32.                     {  
  33.                         if(grantResults[0] == Permission.Granted)  
  34.                         {  
  35.                             if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)  
  36.                             {  
  37.                                 //Request Permision  
  38.                                 ActivityCompat.RequestPermissions(thisnew string[]  
  39.                                 {  
  40.                     Manifest.Permission.Camera  
  41.                                 }, RequestCameraPermisionID);  
  42.                                 return;  
  43.                             }  
  44.                             try  
  45.                             {  
  46.                                 cameraSource.Start(surfaceView.Holder);  
  47.                             }  
  48.                             catch (InvalidOperationException)  
  49.                             {  
  50.                             }  
  51.                         }  
  52.                     }  
  53.                     break;  
  54.             }  
  55.         }  
  56.         protected override void OnCreate(Bundle savedInstanceState)  
  57.         {  
  58.             base.OnCreate(savedInstanceState);  
  59.             // Set our view from the "main" layout resource  
  60.             SetContentView(Resource.Layout.Main);  
  61.             surfaceView = FindViewById<SurfaceView>(Resource.Id.cameraView);  
  62.             txtResult = FindViewById<TextView>(Resource.Id.txtResult);  
  63.             Bitmap bitMap = BitmapFactory.DecodeResource(ApplicationContext  
  64.             .Resources, Resource.Drawable.qrcode);  
  65.             barcodeDetector = new BarcodeDetector.Builder(this)  
  66.                 .SetBarcodeFormats(BarcodeFormat.QrCode)  
  67.                 .Build();  
  68.             cameraSource = new CameraSource  
  69.                 .Builder(this, barcodeDetector)  
  70.                 .SetRequestedPreviewSize(640, 480)  
  71.                 .Build();  
  72.             surfaceView.Holder.AddCallback(this);  
  73.             barcodeDetector.SetProcessor(this);  
  74.         }  
  75.         public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)  
  76.         {  
  77.         }  
  78.         public void SurfaceCreated(ISurfaceHolder holder)  
  79.         {  
  80.             if(ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)  
  81.             {  
  82.                 //Request Permision  
  83.                 ActivityCompat.RequestPermissions(thisnew string[]  
  84.                 {  
  85.                     Manifest.Permission.Camera  
  86.                 }, RequestCameraPermisionID);  
  87.                 return;  
  88.             }  
  89.             try  
  90.             {  
  91.                 cameraSource.Start(surfaceView.Holder);  
  92.             }  
  93.             catch (InvalidOperationException)  
  94.             {  
  95.             }  
  96.         }  
  97.         public void SurfaceDestroyed(ISurfaceHolder holder)  
  98.         {  
  99.             cameraSource.Stop();  
  100.         }  
  101.         public void ReceiveDetections(Detections detections)  
  102.         {  
  103.             SparseArray qrcodes = detections.DetectedItems;  
  104.             if (qrcodes.Size() != 0)  
  105.             {  
  106.                 txtResult.Post(() => {  
  107.                     Vibrator vibrator = (Vibrator)GetSystemService(Context.VibratorService);  
  108.                     vibrator.Vibrate(1000);  
  109.                     txtResult.Text = ((Barcode)qrcodes.ValueAt(0)).RawValue;  
  110.                 });  
  111.             }  
  112.         }  
  113.         public void Release()  
  114.         {  
  115.               
  116.         }  
  117.     }  
  118. }  
Step 7 - Permission From Device
 
We need a permission from the device because we shall be using the device’s camera to capture QR Code. Please add Camera permissions to your AndroidManifest.xml. Open the Solution Explorer-> Properties-> AndroidManifest and let's add the code inside application tags.
  1. <uses-permission android:name="android.permission.CAMERA" />  
  2.     <uses-permission android:name="android.permission.VIBRATE" />  
  3.     <application android:allowBackup="true" android:label="@string/app_name">  
  4.         <meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="barcode" />  
  5.     </application>  
OutPut
 
Running this project, and scanning a QR code, you will have the result like below.
 
 
 
Summary
 
This was the process of creating a QR Code Reader by Mobile Camera app in Xamarin.Android. Please share your comments and feedback.