Monday, 27 July 2015

barcode scanner, qr scanner, zxing android

This post shows you all to integrate zxing scanner into your android project.

The first solution doesn't embed zxing into your app, when your app want to scan, it will launch zxing app to scan, if the user's device doesn't have it, it will automatically open google play to install.

the second solution will embedded zxing into your app, you don't need worry too much about zxing app installation.

The first solution can make your app smaller and it always get benefits of zxing upgrading, because it is a separate app. But it will ask user to install the separate app.

The second solution will make your app bigger but you don't need worry to much about any extra app installing. But the disadvantage is your zxing version is fixed. when zxing upgraded you app still use the old version.


Solution One:


This solution doesn't implement a scanner page in your project, when you request scanner, it actually launch the zxing app for you, and it can return the result to your application.

If don't have zxing installed into your test android device, it will install for you. But your device must has google play!!!



private void initCameralBtn() {
    cameraBtn.setOnClickListener(new View.OnClickListener() {
        @Override        public void onClick(View view) {
            sendAnalyticsEventForCameraScannerButtonTapped();
            IntentIntegrator integrator = new IntentIntegrator(ScannerActivity.this);
            integrator.addExtra("SCAN_WIDTH", CAMERA_BARCODE_SCANNER_WIDTH);
            integrator.addExtra("SCAN_HEIGHT", CAMERA_BARCODE_SCANNER_HEIGHT);
            integrator.addExtra("SCAN_MODE", "QR_CODE_MODE,PRODUCT_MODE");
            integrator.addExtra("PROMPT_MESSAGE", CAMERA_BARCODE_SCANNER_PROMPT_MESSAGE);
            AlertDialog AlertDialog = integrator.initiateScan(IntentIntegrator.PRODUCT_CODE_TYPES);
            if(AlertDialog != null && !Utils.isGooglePlayServicesAvailable()) {// this code will deal with on google play.
                ToastManager.showToast(ScannerActivity.this, Utils.getString(R.string.barcode_scanner_no_google_play), NO_GOOGLE_PLAY_TOAST_DURATION);
            }
        }
    });
}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == IntentIntegrator.REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
            if (scanningResult != null) {
                String barcode;
                barcode = scanningResult.getContents();
                sendAnalyticsEventForReceivingBarcode_CameraScanner(barcode);
                barcodeHandler(ScannerActivity.this, barcode);
            }
        }
    }
}


gradle:

compile 'com.google.zxing:android-integration:3.1.0'


A better one of the code:

If your user's device have the barcode scanner app installed, below code will use the app. If user's device doesn't have the scanner app and it also doesn't have google play, the code will show a notice.



private void initCameralBtn() {
    if(isBarcodeScannerAppAvailable() || isGooglePlayServicesAvailable()){
        cameraBtn.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                sendAnalyticsEventForCameraScannerButtonTapped();
                IntentIntegrator integrator = new IntentIntegrator(ScannerActivity.this);
                integrator.addExtra("SCAN_WIDTH", CAMERA_BARCODE_SCANNER_WIDTH);
                integrator.addExtra("SCAN_HEIGHT", CAMERA_BARCODE_SCANNER_HEIGHT);
                integrator.addExtra("SCAN_MODE", "QR_CODE_MODE,PRODUCT_MODE");
                integrator.addExtra("PROMPT_MESSAGE", CAMERA_BARCODE_SCANNER_PROMPT_MESSAGE);
                integrator.initiateScan(IntentIntegrator.PRODUCT_CODE_TYPES);
            }
        });
    }else{
        scannerLaunchCameraInfo.setText(Utils.getString(R.string.barcode_scanner_no_google_play));
    }
}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == IntentIntegrator.REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
            if (scanningResult != null) {
                String barcode;
                barcode = scanningResult.getContents();
                sendAnalyticsEventForReceivingBarcode_CameraScanner(barcode);
                barcodeHandler(ScannerActivity.this, barcode);
            }
        }
    }
}


public static boolean isBarcodeScannerAppAvailable() {
    final String BS_PACKAGE = "com.google.zxing.client.android";
    Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
    intentScan.addCategory(Intent.CATEGORY_DEFAULT);
    String packageName = findTargetAppPackage(intentScan, GonzalesApplication.getCurrentActivity(), IntentIntegrator.TARGET_ALL_KNOWN);
    if(packageName == null){
        return false;
    }else{
        return true;
    }
}

private static String findTargetAppPackage(Intent intent, Activity activity, List<String> targetApplications) {
    PackageManager pm = activity.getPackageManager();
    List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    if (availableApps != null) {
        for (String targetApp : targetApplications) {
            if (contains(availableApps, targetApp)) {
                return targetApp;
            }
        }
    }
    return null;
}

private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
    for (ResolveInfo availableApp : availableApps) {
        String packageName = availableApp.activityInfo.packageName;
        if (targetApp.equals(packageName)) {
            return true;
        }
    }
    return false;
}



Solution two, embed zxing into your project:

with the core zxing lib only in your gradle file:

compile 'com.google.zxing:core:3.2.0'

compile 'com.journeyapps:zxing-android-embedded:3.0.2@aar'

Then you don't need to check google play and if the scanner app is installed or not.

The zxing scanner app is embedded into your app.

The code:


private void initCameralBtn() {
    cameraBtn.setOnClickListener(new View.OnClickListener() {
        @Override        public void onClick(View view) {
            sendAnalyticsEventForCameraScannerButtonTapped();
            IntentIntegrator integrator = new IntentIntegrator(ScannerActivity.this);
            integrator.addExtra("SCAN_WIDTH", CAMERA_BARCODE_SCANNER_WIDTH);
            integrator.addExtra("SCAN_HEIGHT", CAMERA_BARCODE_SCANNER_HEIGHT);
            integrator.addExtra("SCAN_MODE", "QR_CODE_MODE,PRODUCT_MODE");
            integrator.addExtra("PROMPT_MESSAGE", CAMERA_BARCODE_SCANNER_PROMPT_MESSAGE);
            integrator.initiateScan(IntentIntegrator.PRODUCT_CODE_TYPES);
        }
    });
}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == IntentIntegrator.REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
            if (scanningResult != null) {
                String barcode;
                barcode = scanningResult.getContents();
                sendAnalyticsEventForReceivingBarcode_CameraScanner(barcode);
                barcodeHandler(ScannerActivity.this, barcode);
            }
        }
    }
}








No comments:

Post a comment