# 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](/kvalifika-1/integration/integration-guide.md) and [Initial Setup](/kvalifika-1/integration/initial-setup.md).

{% 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](/kvalifika-1/integration/initial-setup.md#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](/kvalifika-1/mobile-sdk/android.md#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.** { *; }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kvalifika.gitbook.io/kvalifika-1/mobile-sdk/android.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
