# Android QR Scan SDK
source: https://developer.mastercard.com/mastercard-merchant-presented-qr/documentation/device-sdks/android-qr-scan-sdk/index.md

The Android QR Scan SDK can be used by Originating Institutions and Wallet Providers to scan the QR code and parse and verify the content in the Android application. This SDK uses the [Java Core SDK](https://developer.mastercard.com/mastercard-merchant-presented-qr/documentation/device-sdks/java-core-sdk/index.md) to parse and verify the QR code content.

## Download Libraries {#download-libraries}

[qr-scan-sdk-release-1.0.5.aar](https://static.developer.mastercard.com/content/mastercard-merchant-presented-qr/sdk-files/qr-scan-sdk-release-1.0.5.aar)

This library is based on [ZXing Android Embedded](https://github.com/journeyapps/zxing-android-embedded).

## Features {#features}

* Can be used via Intents (little code required)
* Can be embedded in an Activity, for advanced customization of UI and logic
* Scanning can be performed in landscape or portrait mode
* Camera is managed in a background thread, for fast startup time
* Return constructed object for the correct Push Payment QR code

## Adding aar Dependency with Gradle {#adding-aar-dependency-with-gradle}

This library supports KitKat and later versions of Android (API level 19+).

1. Copy the **qr-scan-sdk-release-1.0.5.aar** and **pushpayment-core-sdk-2.1.1.jar** into your project libs folder.
2. Configure your build.gradle file:

* Gradle

```Gradle
repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation (name: 'qr-scan-sdk-release-1.0.5', ext: 'aar')
    implementation 'com.journeyapps:zxing-android-embedded:3.4.0'

    //Other dependancies required by the android application
    //Note : Appcompat minumum version supported is v7:23.1.0
}

android {

    // Minimum version supported is 24.0.0. Older versions may give compile errors
    buildToolsVersion '29.0.3' 
}
```

## Usage with IntentIntegrator {#usage-with-intentintegrator}

Launch the intent with the default options:
* Java

```Java
new PPIntentIntegrator(this).initiateScan(); // `this` is the current Activity 

// Get the results:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        PushPaymentData qrcode = (PushPaymentData) data.getSerializableExtra(PPIntents.PUSH_PAYMENT_DATA);
        if (qrcode != null) {
            try {
                String qrString = qrcode.generatePushPaymentString();
                Toast.makeText(this, qrString, Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                //do something for the exception
            }
        }
    } else if (resultCode == RESULT_CANCELED) {
        if (data != null) {
            FormatException e = (FormatException) data.getSerializableExtra(PPIntents.PARSE_ERROR); // get the exception reason
            if (e != null) {
                Toast.makeText(this, "Exception: "+e.getMessage(), Toast.LENGTH_LONG).show();
            }
            // you can also check if the partial qrcode is returned, then grab any data you want from it
            PushPaymentData qrcode = (PushPaymentData) data.getSerializableExtra(PPIntents.PUSH_PAYMENT_DATA);
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}
```

Use from a Fragment:
* Java

```Java
PPIntentIntegrator.forFragment(this).initiateScan(); // `this` is the current Fragment 

// If you're using the support library, use PPIntentIntegrator.forSupportFragment(this) instead. 
```

Customize options:
* Java

```Java
PPIntentIntegrator integrator = new PPIntentIntegrator(this);
integrator.setCameraId(0);  // Use a specific camera of the device 
integrator.setBeepEnabled(false);
integrator.initiateScan();
```

## Changing the Orientation {#changing-the-orientation}

To change the orientation, specify the orientation in your **AndroidManifest.xml** and let the **ManifestMerger** update the Activity's definition:
* XML

```XML
<activity
        android:name="com.mastercard.mpqr.pushpayment.scan.activity.PPCaptureActivity"
        android:screenOrientation="fullSensor"
        tools:replace="screenOrientation" />
```

Code sample:
* Java

```Java
PPIntentIntegrator integrator = new PPIntentIntegrator(this);
integrator.setOrientationLocked(false);
integrator.initiateScan();
```

## Customization and Advanced Options {#customization-and-advanced-options}

### QR Code Scan Theme Customization {#qr-code-scan-theme-customization}

Add the new style in the resource file:
* XML

```XML
<style name="CustomizeScanTheme" parent="ppscan_CaptureTheme">
    <item name="colorAccent">@color/colorAccent</item>
</style>
```

Change the theme for **PPCaptureActivity** from your project app module **AndroidManifest.xml**:
* XML

```XML
<activity
    android:name="com.mastercard.mpqr.pushpayment.scan.activity.PPCaptureActivity"
    android:screenOrientation="portrait"
    android:theme="@style/CustomizeScanTheme"
    tools:replace="screenOrientation, theme" />
```

### Layout and Function Customization {#layout-and-function-customization}

Create a new activity:
* Java

```Java
package com.mastercard.labs.sng.qrscantester;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

import com.google.zxing.client.android.Intents;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.mastercard.mpqr.pushpayment.scan.activity.PPCaptureActivity;


public class CustomizedCaptureActivity extends PPCaptureActivity {
    //you can define your own return code
    public static final int RESULT_OK_WITH_MERCHANT_ID = 15;
    public static final String MERCHANT_ID_INTENT = "MERCHANT_ID_INTENT";

    private EditText merchantIdEditText;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //add ref to your new element
        merchantIdEditText = (EditText) findViewById(R.id.edit_merchant_id);
    }

    @Override
    protected DecoratedBarcodeView initializeContent() {
        //specify the new customized layout
        this.setContentView(R.layout.activity_pp_capture_customized);
        return (DecoratedBarcodeView)this.findViewById(com.mastercard.mpqr.pushpayment.scan.R.id.zxing_barcode_scanner);
    }

    //you can bind your new event
    public void onOKPressed(View view) {
        String merchantId = merchantIdEditText.getText().toString();
        Intent intent = new Intent(Intents.Scan.ACTION);
        intent.putExtra(MERCHANT_ID_INTENT, merchantId);
        this.setResult(RESULT_OK_WITH_MERCHANT_ID, intent);
        finish();
    }

    @Override
    public void toggleTorch(View view) {
        super.toggleTorch(view);
    }

    @Override
    public void goBack(View view) {
        super.goBack(view);
    }
}
```

Sample customized layout **activity_pp_capture_customized.xml**:
* XML

```XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="CustomizedCaptureActivity">
 
    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/zxing_barcode_scanner"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:zxing_scanner_layout="@layout/sample_custom_scanner" />
 
    <ImageView
        android:id="@+id/torch_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_margin="12dp"
        android:onClick="toggleTorch"
        android:src="@drawable/ic_torch" />
 
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_margin="12dp"
        android:onClick="goBack"
        android:src="@drawable/ic_arrow_back" />
 
    <LinearLayout
        android:layout_marginTop="48dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/background_light">
        <EditText
            android:id="@+id/edit_merchant_id"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="9"
            android:inputType="number"
            android:textColor="@color/colorAccent"
            android:hint="merchant id"/>
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:text="@string/zxing_button_ok"
            android:onClick="onOKPressed"/>
    </LinearLayout>
 
    <Space
        android:id="@+id/spacer2"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:layout_gravity="center" />
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/spacer2"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:background="@color/zxing_transparent"
        android:fontFamily="sans-serif-thin"
        android:text="@string/string_scan_qr_code"
        android:textColor="@color/colorWhite"
        android:textSize="16sp" />
 
</RelativeLayout>
```

Sample customized scan indicator layout **sample_custom_scanner.xml**:
* XML

```XML
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto">
 
    <com.journeyapps.barcodescanner.BarcodeView
        android:id="@+id/zxing_barcode_surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:zxing_framing_rect_width="200dp"
        app:zxing_framing_rect_height="200dp"/>
 
    <com.mastercard.mpqr.pushpayment.scan.view.PPQrFinderIndicatorView
        android:id="@+id/zxing_viewfinder_view"
        app:ppscan_corner_length="40dp"
        app:ppscan_corner_width="6dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:zxing_possible_result_points="?attr/colorAccent"
        app:ppscan_corner_color="?attr/colorAccent"
        app:ppscan_laser_color="?attr/colorAccent"
        app:zxing_result_view="@color/zxing_custom_result_view"
        app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"
        />
 
    <!-- didn't use the status actually -->
    <TextView
        android:id="@+id/zxing_status_view"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:background="@color/zxing_transparent"
        android:text="@string/zxing_msg_default_status"
        android:textColor="@color/zxing_status_text"/>
 
</merge>
```

