# Android

Use Kvalifika SDK to easily integrate into a native Android project. Before integrating Kvalifika, it is recommended to follow the steps described in [Integration Guide](https://kvalifika.gitbook.io/kvalifika-1/integration/integration-guide) and [Initial Setup](https://kvalifika.gitbook.io/kvalifika-1/integration/initial-setup).

{% hint style="warning" %}
Naming of the properties and functions might be slightly modified depending on the version.
{% endhint %}

## Installation

&#x20;Add the following to the project's main `build.gradle` file:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
allprojects {
    repositories {
        // Existing repositories, like google() and jcenter()
        maven { url 'https://s3.eu-central-1.amazonaws.com/com.kvalifika.sdk' }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
allprojects {
    repositories {
        // Existing repositories, like google() and jcenter()
        maven { url 'https://s3.eu-central-1.amazonaws.com/com.kvalifika.sdk' }
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
&#x20;Please use `minSdkVersion` `21` in your `build.gradle (Module)` file
{% endhint %}

&#x20;  To install Kvalifika Android SDK, add the following to `build.gradle (Module)` file:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
dependencies {
  // Insert line below to include our client library as a dependency.
  implementation 'com.kvalifika:sdk:0.7.0'
}
```

{% endtab %}

{% tab title="Java" %}

```java
dependencies {
  // Insert line below to include our client library as a dependency.
  implementation 'com.kvalifika:sdk:0.7.0'
}
```

{% endtab %}
{% endtabs %}

## Initialize the SDK

import Kvalifika:

```kotlin
import com.kvalifika.sdk.KvalifikaSDK
import com.kvalifika.sdk.KvalifikaSDKLocale
import com.kvalifika.sdk.KvalifikaSDKCallback
import com.kvalifika.sdk.KvalifikaSDKError
```

After that, you need to initialize SDK with **your `appId`** and **`secretKey`**

{% hint style="info" %}
**`appId`** is Application ID and **secretKey** is Application Secret Key, generated from Admin Panel. See [Initial Setup](https://kvalifika.gitbook.io/kvalifika-1/integration/initial-setup#retrieve-application-ids) for details.
{% endhint %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
class MainActivity : AppCompatActivity() {
	 private lateinit var sdk: KvalifikaSDK
 	 private val appId: String = "YOUR APP ID"

	 override fun onCreate(savedInstanceState: Bundle?) {
			super.onCreate(savedInstanceState)
			setContentView(R.layout.activity_main)

			sdk = KvalifikaSDK.Builder(this, appId)
					.locale(KvalifikaSDKLocale.EN)
					.build()
	 }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class MainActivity extends AppCompatActivity {
	private KvalifikaSDK sdk;

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

		String appId = "YOU APP ID";
		setContentView(R.layout.activity_main);

		sdk = new KvalifikaSDK.Builder(this, appId)
			.locale(KvalifikaSDKLocale.EN)
			.build();
	 }
}
```

{% endtab %}
{% endtabs %}

## Start Verification

&#x20;Call `sdk.startSession()` on button click event:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
class MainActivity : AppCompatActivity() {
	 private lateinit var sdk: KvalifikaSDK
 	 private val appId: String = "YOUR APP ID"

	 override fun onCreate(savedInstanceState: Bundle?) {
			super.onCreate(savedInstanceState)
			setContentView(R.layout.activity_main)

			sdk = KvalifikaSDK.Builder(this, appId)
					.locale(KvalifikaSDKLocale.GE)
					.build()

	 }

	 // Start verification on button click
	 fun onVerificationPress(view: View?) {
			sdk.startSession()
	 }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class MainActivity extends AppCompatActivity {
	private KvalifikaSDK sdk;

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

		String appId = "YOU APP ID";
		setContentView(R.layout.activity_main);

		sdk = new KvalifikaSDK.Builder(this, appId)
			.locale(KvalifikaSDKLocale.EN)
			.build();
	 }

	 public void onVerificationPress(View view) {
		sdk.startSession();
	 }
}
```

{% endtab %}
{% endtabs %}

## Handling Verifications

It's useful to know that whether a user has completed the verification flow or canceled it. For this, you can implement the callback methods.

### Callback Methods

| Method       | Description                                                                                        |
| ------------ | -------------------------------------------------------------------------------------------------- |
| onInitialize | This callback method is triggered when SDK is initialized.                                         |
| onStart      | This callback method is triggered when the user starts verification.                               |
| onFinish     | This callback method is triggered when the user completes verification. Get session data here.     |
| onError      | This callback method is triggered on error  (see [Error Codes](#error-codes) for more information) |

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
sdk.callback(object : KvalifikaSDKCallback {
    override fun onInitialize() {
        Log.d("MainActivity", "initialized")
    }

    override fun onStart(sessionId: String) {
        Log.d("MainActivity", "started")
    }

    override fun onFinish(sessionId: String) {
		// Fetch session data here from your server
    }

    override fun onError(error: KvalifikaSDKError, message: String?) {
        if(error == KvalifikaSDKError.INVALID_APP_ID) {
    		Log.d("MainActivity", "Invalid App ID")
    	}

        if (error == KvalifikaSDKError.USER_CANCELLED) {
            Toast.makeText(applicationContext, "User cancelled", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.TIMEOUT) {
            Toast.makeText(applicationContext, "Timeout", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.SESSION_UNSUCCESSFUL) {
            Toast.makeText(applicationContext, "Session failed", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.ID_UNSUCCESSFUL) {
            Toast.makeText(applicationContext, "ID scan failed", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.CAMERA_PERMISSION_DENIED) {
            Toast.makeText(applicationContext, "Camera permission denied", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.LANDSCAPE_MODE_NOT_ALLOWED) {
            Toast.makeText(applicationContext, "Landscape mode is not allowed", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.REVERSE_PORTRAIT_NOT_ALLOWED) {
            Toast.makeText(applicationContext, "Reverse portrait is not allowed", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.FACE_IMAGES_UPLOAD_FAILED) {
            Toast.makeText(applicationContext, "Could not upload face images", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.DOCUMENT_IMAGES_UPLOAD_FAILED) {
            Toast.makeText(applicationContext, "Could not upload Id card or passport images", Toast.LENGTH_LONG).show()
        }
        
        if (error == KvalifikaSDKError.NO_MORE_ATTEMPTS) {
            Toast.makeText(applicationContext, "You have reached maximum attempts", Toast.LENGTH_LONG).show()
        }

        if (error == KvalifikaSDKError.UNKNOWN_INTERNAL_ERROR) {
            Toast.makeText(applicationContext, "Unknown error happened", Toast.LENGTH_LONG).show()
        }
    }
})
```

{% endtab %}

{% tab title="Java" %}

```java
sdk.callback(new KvalifikaSDKCallback() {
    @Override
 	public void onInitialize() {
        Log.d("MainActivity", "initialized");
    }

    @Override
 	public void onStart(@NotNull String sessionId) {
        Log.d("MainActivity", "started");
    }

    @Override
 	public void onFinish(@NotNull String sessionId) {
        Log.d("MainActivity", "finished");
    }

    @Override
 	public void onError(@NotNull KvalifikaSDKError error, String message) {
        if (error == KvalifikaSDKError.INVALID_APP_ID) {
            Log.d("MainActivity", "Invalid App ID");
        }

        if (error == KvalifikaSDKError.USER_CANCELLED) {
            Toast.makeText(getApplicationContext(), "User cancelled", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.TIMEOUT) {
            Toast.makeText(getApplicationContext(), "Timeout", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.SESSION_UNSUCCESSFUL) {
            Toast.makeText(getApplicationContext(), "Session failed", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.ID_UNSUCCESSFUL) {
            Toast.makeText(getApplicationContext(), "ID scan failed", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.CAMERA_PERMISSION_DENIED) {
            Toast.makeText(getApplicationContext(), "Camera permission denied", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.LANDSCAPE_MODE_NOT_ALLOWED) {
            Toast.makeText(getApplicationContext(), "Landscape mode is not allowed", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.REVERSE_PORTRAIT_NOT_ALLOWED) {
            Toast.makeText(getApplicationContext(), "Reverse portrait is not allowed", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.FACE_IMAGES_UPLOAD_FAILED) {
            Toast.makeText(getApplicationContext(), "Could not upload face images", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.DOCUMENT_IMAGES_UPLOAD_FAILED) {
            Toast.makeText(getApplicationContext(), "Could not upload Id card or passport images", Toast.LENGTH_LONG).show();
        }
        
        if (error == KvalifikaSDKError.NO_MORE_ATTEMPTS) {
            Toast.makeText(getApplicationContext(), "You have reached maximum attempts", Toast.LENGTH_LONG).show();
        }

        if (error == KvalifikaSDKError.UNKNOWN_INTERNAL_ERROR) {
            Toast.makeText(getApplicationContext(), "Unknown error happened", Toast.LENGTH_LONG).show();
        }
    }
});
```

{% endtab %}
{% endtabs %}

## Error Codes

| Error Code                       | Description                                                                              |
| -------------------------------- | ---------------------------------------------------------------------------------------- |
| INVALID\_APP\_ID                 | Kvalifika App Id is incorrect                                                            |
| USER\_CANCELLED                  | User canceled before completing verification.                                            |
| TIMEOUT                          | Canceled due to inactivity.                                                              |
| SESSION\_UNSUCCESSFUL            | The Session was not performed successfully                                               |
| ID\_UNSUCCESSFUL                 | The ID Scan was not performed successfully and identity document data was not generated. |
| CAMERA\_PERMISSION\_DENIED       | Camera is required but access is prevented by user settings.                             |
| LANDSCAPE\_MODE\_NOT\_ALLOWED    | Verification was canceled because the device is in landscape mode.                       |
| REVERSE\_PORTRAIT\_NOT\_ALLOWED  | Verification was canceled because the device is in reverse portrait mode.                |
| FACE\_IMAGES\_UPLOAD\_FAILED     | Could not upload face images. Internal request failed.                                   |
| DOCUMENT\_IMAGES\_UPLOAD\_FAILED | Could not upload ID card or passport images. Internal request failed.                    |
| NO\_MORE\_ATTEMPTS               | User has reached maximum limit of attempts                                               |
| UNKNOWN\_INTERNAL\_ERROR         | Session failed because of an unhandled internal error.                                   |

## UI Customizations

### Appearance

It is possible to customize the logo and icons and provide drawable resources.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
sdk = KvalifikaSDK.Builder(this, appId, secretKey)
	.locale(KvalifikaSDKLocale.EN)
	.logo(R.drawable.logo)
	.documentIcon(R.drawable.document_icon)
	.activeFlashIcon(R.drawable.flash_on)
	.inactiveFlashIcon(R.drawable_flash_off)
	.cancelIcon(R.drawable.cancel_icon)
	.build()
```

{% endtab %}

{% tab title="Java" %}

```java
sdk = KvalifikaSDK.Builder(this, appId, secretKey)
	.locale(KvalifikaSDKLocale.EN)
	.logo(R.drawable.logo)
	.documentIcon(R.drawable.document_icon)
	.activeFlashIcon(R.drawable.flash_on)
	.inactiveFlashIcon(R.drawable_flash_off)
	.cancelIcon(R.drawable.cancel_icon)
	.build()
```

{% endtab %}
{% endtabs %}

### Language

It is possible to set locale when initializing SDK. Supported locales are:

| Code | Language |
| ---- | -------- |
| EN   | English  |
| GE   | Georgian |
| RU   | Russian  |
| SP   | Spanish  |

{% tabs %}
{% tab title="Kotlin" %}

```swift
sdk = KvalifikaSDK.Builder(this, appId, secretKey)
        .locale(KvalifikaSDKLocale.EN)
        .build()
```

{% endtab %}

{% tab title="Java" %}

```java
KvalifikaSDK sdk = new KvalifikaSDK.Builder(this, appId, secretKey)
        .locale(KvalifikaSDKLocale.EN)
        .build();
```

{% endtab %}
{% endtabs %}

## Development Mode

Without specifying mode SDK uses <https://api.kvalifika.com>

With development mode ON SDK uses <https://apistaging.kvalifika.com>

{% tabs %}
{% tab title="Kotlin" %}

```java
sdk = KvalifikaSDK.Builder(this, appId)
        .development(true)
        .build()
```

{% endtab %}

{% tab title="Java" %}

```java
KvalifikaSDK sdk = new KvalifikaSDK.Builder(this, appId)
        .development(true)
        .build();
```

{% endtab %}
{% endtabs %}

## ProGuard

If you are using ProGuard in the release build, add the following options:

```java
-keep class com.facetec.sdk.** { *; }
```
