---
title: Android
description: Integrasikan Human Token Journey ke dalam aplikasi Android Anda menggunakan Custom Tabs — ringan, aman, dan tanpa WebView.
canonical: https://developer.unico.io/id/human-token/integrations/app/android/link-integration
locale: id
generated_by: markdown-export
---

# Android

Integrasikan Human Token Journey ke dalam aplikasi Android Anda menggunakan Custom Tabs.

Custom Tabs meluncurkan Human Token Journey di tab browser dalam aplikasi Anda. Saat perjalanan selesai, browser mengarahkan ulang ke skema URL kustom Anda dan aplikasi Anda menangkapnya.

### Prasyarat

- Android 8 (API 26) atau lebih baru
- `androidx.browser:browser:1.5.0`
- Skema URL unik untuk aplikasi Anda (misalnya `myapp`)

### Langkah 1: Tambahkan dependensi

Di `build.gradle` Anda:

```groovy
implementation("androidx.browser:browser:1.5.0")
```

### Langkah 2: Tentukan skema URL Anda

Pilih skema unik (misalnya `myapp`). Ini digunakan sebagai `callbackUri` saat membuat proses:

```
callbackUri: myapp://callback
```

### Langkah 3: Buat activity

```kotlin
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent

class HumanTokenActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val url = intent.getStringExtra(EXTRA_PROCESS_URL) ?: return finish()

        CustomTabsIntent.Builder()
            .build()
            .launchUrl(this, Uri.parse(url))
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        intent.data?.let { uri ->
            if (uri.scheme == "myapp") {
                // Journey completed — send processId to your backend
                val processId = uri.getQueryParameter("id")
                handleResult(processId)
            }
        }
    }

    private fun handleResult(processId: String?) {
        // Fetch the result from your backend via Get Process
        finish()
    }

    companion object {
        const val EXTRA_PROCESS_URL = "process_url"
    }
}
```

### Langkah 4: Konfigurasi AndroidManifest.xml

```xml
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

<activity
    android:name=".HumanTokenActivity"
    android:launchMode="singleTop"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="myapp" android:host="callback" />
    </intent-filter>
</activity>
```

`singleTop` memastikan Android memanggil `onNewIntent()` pada activity yang sudah ada, bukan membuat yang baru.

### Langkah 5: Mulai perjalanan

```kotlin
val intent = Intent(this, HumanTokenActivity::class.java)
    .putExtra(HumanTokenActivity.EXTRA_PROCESS_URL, processLink)
startActivity(intent)
```

### Ringkasan file

| File | Tujuan |
|---|---|
| `build.gradle` | Dependensi `androidx.browser` |
| `HumanTokenActivity.kt` | Peluncuran Custom Tabs + penanganan redirect |
| `AndroidManifest.xml` | Intent filter untuk skema URL Anda |

---

### Menggunakan WebView sebagai pengganti Custom Tabs

> **Peringatan:** Custom Tabs adalah pendekatan yang direkomendasikan. Lebih aman, menangani redirect secara native, dan memerlukan konfigurasi lebih sedikit. Gunakan WebView hanya jika Custom Tabs bukan opsi dalam proyek Anda.

Jika Anda harus menggunakan `WebView`, journey memerlukan JavaScript, penyimpanan DOM, autoplay media, dan izin kamera/geolokasi untuk diberikan secara eksplisit. Tanpa pengaturan ini, frame tangkapan tidak akan dimuat atau kamera tidak akan aktif.

```kotlin
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
webView.settings.setGeolocationEnabled(true)

webView.webChromeClient = object : WebChromeClient() {
    override fun onPermissionRequest(request: PermissionRequest) {
        if (PermissionRequest.RESOURCE_VIDEO_CAPTURE in request.resources) {
            request.grant(arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
        } else {
            request.deny()
        }
    }

    override fun onGeolocationPermissionsShowPrompt(
        origin: String,
        callback: GeolocationPermissions.Callback
    ) {
        callback.invoke(origin, true, false)
    }
}
```

Anda juga harus mendeklarasikan izin `CAMERA`, `INTERNET`, dan `ACCESS_FINE_LOCATION` di `AndroidManifest.xml` dan meminta izin kamera dan lokasi saat runtime sebelum memuat URL journey.

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```