Skip to content

Android SDK

SDK Android untuk Android 5.0+ (API 21+), dikemas sebagai satu file .aar. Aplikasi berbasis Compose maupun View tradisional sama-sama didukung; SDK tidak bergantung pada framework UI tertentu.

Demo di GitHub

📦

Captcha-La/android-demo — contoh lengkap dan dapat dijalankan dengan seluruh langkah integrasi.

Instalasi

The SDK ships as a single .aar you download from the CaptchaLa dashboard. Drop it into your app module's libs/ folder and reference it from Gradle:

groovy
// settings.gradle (or repositories block)
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}

// app/build.gradle
android {
    defaultConfig {
        minSdk 21
    }
}

dependencies {
    implementation 'la.captcha:captchala:1.0.2'   // Maven Central
}

Atau unduh AAR untuk integrasi manual:

groovy
// app/build.gradle (drop captchala.aar into app/libs/)
android {
    defaultConfig {
        minSdk 21
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }
}

dependencies {
    implementation files('libs/captchala.aar')
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
}

Download: dash.captcha.la/downloads (latest AAR).

xml
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Build and install the demo with:

bash
./gradlew installDebug

Mulai cepat

kotlin
import la.captcha.sdk.CaptchalaClient
import la.captcha.sdk.CaptchalaConfig
import la.captcha.sdk.CaptchalaError
import la.captcha.sdk.CaptchalaListener
import la.captcha.sdk.CaptchalaResult

class LoginActivity : ComponentActivity() {

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

        // 1. Fetch a one-shot server_token from YOUR backend
        //    (which calls the CaptchaLa server API with X-App-Key + X-App-Secret).
        val serverToken = runBlocking { fetchServerTokenFromYourBackend() }

        // 2. Build config — destroy any prior client so a fresh state is built.
        CaptchalaClient.destroy()
        val client = CaptchalaClient.getClient(applicationContext).init(
            CaptchalaConfig.Builder()
                .appKey("YOUR_APP_KEY")
                .action("login")            // login, register, pay, …
                .lang("en")                 // en, zh-CN, zh-TW, ja, ko, ms, vi, id
                .theme("light")             // "light" | "dark"
                .enableVoice(true)
                .enableOfflineMode(true)
                .serverToken(serverToken)
                .onServerTokenExpired { fetchServerTokenFromYourBackend() }
                .build()
        )

        // 3. Listen for terminal events.
        client.setListener(object : CaptchalaListener {
            override fun onReady() { /* challenge UI ready */ }
            override fun onSuccess(result: CaptchalaResult) {
                // Send result.passToken to your backend for validation.
                sendToBackend(result.passToken)
            }
            override fun onFail(error: CaptchalaError)  { /* recoverable */ }
            override fun onError(error: CaptchalaError) { /* terminal */ }
            override fun onClose() { /* user dismissed */ }
        })

        // 4. Open the CAPTCHA from a button tap.
        findViewById<Button>(R.id.btnVerify).setOnClickListener {
            client.verify(this)
        }
    }
}

API utama

SimbolTujuan
CaptchalaClient.getClient(ctx)Titik masuk singleton. Mengembalikan klien bersama yang terikat pada konteks aplikasi.
CaptchalaConfig.Builder()Builder fluent untuk appKey, action, lang, theme, enableVoice, enableOfflineMode, serverToken.
init(config)Inisialisasi klien dengan CaptchalaConfig yang sudah dibangun. Aman dipanggil ulang (state dibangun ulang).
setListener(listener)Mendaftarkan CaptchalaListener untuk callback onReady, onSuccess, onFail, onError, onClose.
verify(activity)Membuka CAPTCHA di atas Activity yang diberikan. Hasil dikirim lewat listener.
CaptchalaResultBerisi passToken, challengeId, ttl, isOffline, isClientOnly. Kirim passToken ke backend Anda.
CaptchalaClient.destroy()Menghancurkan singleton (melepaskan WebView, handle native). Panggil dari Activity.onDestroy bila sering re-init.

Validasi sisi server

Teruskan result.passToken (atau result.token) ke backend Anda lalu validasi melalui API CaptchaLa. Jangan pernah mengekspos X-App-Secret di kode klien.

bash
POST https://apiv1.captcha.la/v1/validate
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json

{ "pass_token": "<result.passToken>", "client_ip": "<end-user IP>" }

Lihat Referensi API untuk endpoint validasi lengkap dan alur X-App-Key / X-App-Secret.

Pemecahan masalah

  • UnsatisfiedLinkError saat startup
    Pastikan abiFilters Anda mencakup armeabi-v7a, arm64-v8a, x86, x86_64 sehingga semua bentuk perangkat menemukan native lib yang cocok. Lihat app/build.gradle di demo.

  • ProGuard / R8 menghapus kelas SDK pada build release
    Tambahkan aturan keep untuk paket SDK, mis. -keep class la.captcha.sdk.** { *; } dan -dontwarn la.captcha.sdk.** di proguard-rules.pro.

  • minSdkVersion terlalu rendah
    SDK membutuhkan minSdkVersion 21 (Android 5.0). Target yang lebih rendah akan gagal saat compile.

  • Lalu lintas HTTP cleartext diblokir
    Manifest Anda sebaiknya tetap android:usesCleartextTraffic="false" (demo melakukannya). Endpoint CaptchaLa hanya HTTPS.

Persyaratan

  • Android 5.0+ (minSdkVersion 21)
  • AndroidX (compileSdk 33+)
  • Kotlin 1.8+ or equivalent Java toolchain (Java 17 source / target)
  • ABIs: armeabi-v7a, arm64-v8a, x86, x86_64

MIT-licensed examples · CaptchaLa is operated independently