Mobile Vision - Scan Barcode chưa bao giờ đơn giản đến thế

Giới thiệu về google vision

Mobile Vision API là một framework của Google cho phép chúng ta tìm kiếm các đối tượng trên ảnh và video. Đối tượng ở đây có thể là khuôn mặt, barcode, qrcode, chữ ... Mobile Vision bao gồm

  1. Detector có nhiệm vụ quan sát, xác định vị trí và mô tả các đối tượng có trong khung hình hoặc trong video
  2. API call back vị trí của các đối tượng đó trong video.

Hiện tại Mobile Vision đang cung cấp các tính năng như sau

  1. Face detectors
  2. Text detectors
  3. Barcode detectors

Chúng có thể áp dụng riêng rẽ hoặc cùng nhau.

  1. Trong bài viết đầu tiên mình sẽ hướng dẫn các bạn sử dụng tính năng thứ 3 Barcode detectors của Mobile Vision

Barcode Detectors

Sau bản release Google Play services 7.8 thì Barcode Detectors của Mobile Vision đã được cung cấp các API phát hiện mã vạch đọc và giải mã vô số các loại mã vạch khác nhau, nhanh chóng, dễ dàng và đặc biệt là locally không phải truy xuất tới bất kì API nào cả.

Nào, chúng ta bắt đầu nhé.

1. Khởi tạo App

  • Mở Android Studio và khởi tạo Project có tên là Google Vision Bar Code nhé

2. Config file Build Gradle

  • Mở app/build.gradle và compile google play service vision để có thể sử dụng api barcode detector
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.google.android.gms:play-services-vision:9.4.0+'
}

Ok giờ là xong các bước setup bh mình sẽ tiến hành code.

3. Tạo giao diện

Ứng dụng của mình sẽ có 1 màn hình để scan QR code từ CAMERA sau khi scan có kết quả thì sẽ show thông báo cho user qua Toast Mở file activity_main.xml và thêm đoạn code sau

<?xml version="1.0" encoding="utf-8"?>
<SurfaceView
  android:id="@+id/camera_view"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.example.toand.googlevisionbarcode.ScanActivity"
  />

Chỉ có 1 màn hình hiển thị CAMERA nên mình sẽ khai báo SurfaceView

4. Xin cấp quyền CAMERA

Vì ứng dụng của chúng ta sử dụng CAMERA để quét QR code nên cần request quyền android.permission.CAMERA" Mở file Android.manifest và thêm quyền như sau

<uses-permission android:name="android.permission.CAMERA"/>

Vì đây là một quyền nguy hiển nên ta cần request permision run time cho các dòng máy M trở lên

Mở file ScanActivity.java và xin cấp quyền như sau

@Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     if (ActivityCompat.checkSelfPermission(ScanActivity.this,
         Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
         ActivityCompat.requestPermissions(ScanActivity.this,
             new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA);
         return;
             }
     
     //..... 
 }
 @SuppressLint("MissingPermission")
 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
     @NonNull int[] grantResults) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     if (requestCode == REQUEST_CAMERA && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
         try {
          //..
         } catch (IOException e) {
             e.printStackTrace();
         }
     }else{
         finish();
     }
 }

Viết code scan QR

Như đã đề cập ở trên thì movile Vision gồm có 2 phần DetectorCallBack

  • Chúng ta cần khai báo BarcodeDetector và call back Detector.Processor<Barcode>
  • Vì nhận diện thông qua CAMERA nên tâ cần khai báo thêm CameraSource giúp lắng nghe mọi sự thay đổi của CAMERA.

Khi BarcodeDetector nhận được sự thay đổi bất kì từ CAMERA thông qua CameraResource sẽ trả lại chúng ta thông qua menthod public void receiveDetections(Detector.Detections<Barcode> detections)

Mở file ScanActivity.java và thêm đoạn lệnh sau

public class ScanActivity extends AppCompatActivity {
   private static final int REQUEST_CAMERA = 1;
   private SurfaceView mCameraPreview;
   private BarcodeDetector mBarcodeDetector;
   private CameraSource mCameraSource;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       if (ActivityCompat.checkSelfPermission(ScanActivity.this,
           Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
           ActivityCompat.requestPermissions(ScanActivity.this,
               new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA);
           return;
       }

       mCameraPreview = findViewById(R.id.camera_view);

       mBarcodeDetector =
           new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.QR_CODE).build();

       mCameraSource = new CameraSource.Builder(this, mBarcodeDetector).setFacing(
           CameraSource.CAMERA_FACING_BACK)
           .setRequestedFps(35.0f)
           .setAutoFocusEnabled(true)
           .build();

       mCameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
           @Override
           public void surfaceCreated(SurfaceHolder surfaceHolder) {

               try {
                   mCameraSource.start(mCameraPreview.getHolder());
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }

           @Override
           public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

           }

           @Override
           public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
               mCameraSource.stop();
           }
       });

       mBarcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
           @Override
           public void release() {
           }

           @Override
           public void receiveDetections(Detector.Detections<Barcode> detections) {
               SparseArray<Barcode> barcodes = detections.getDetectedItems();
               if (barcodes != null && barcodes.size() > 0) {
                   Toast.makeText(ScanActivity.this, barcodes.valueAt(0).displayValue,
                       Toast.LENGTH_SHORT).show();
               }
           }
       });
   }
 }

Trên đây mình đã giới thiệu với các bạn về Google Vision - Detector BarCode các bạn có thể tham khảo thêm về Google Vision - Detector BarCode tại đây

Github: https://github.com/DoanVanToan/GoogleVisionBarCode Chúc các bạn học tốt.!