Skip to content

Android SDK

SDK Android cho Android 5.0+ (API 21+), đóng gói thành một file .aar duy nhất. Hỗ trợ cả Compose và View truyền thống — SDK không phụ thuộc vào framework UI.

Demo trên GitHub

📦

Captcha-La/android-demo — ví dụ đầy đủ, có thể chạy được, kèm mọi bước tích hợp.

Cài đặt

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
}

Hoặc tải xuống AAR để tích hợp thủ công:

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

Bắt đầu nhanh

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 chính

Ký hiệuMục đích
CaptchalaClient.getClient(ctx)Điểm vào singleton. Trả về client dùng chung gắn với application context.
CaptchalaConfig.Builder()Builder dạng fluent cho appKey, action, lang, theme, enableVoice, enableOfflineMode, serverToken.
init(config)Khởi tạo client với CaptchalaConfig đã được build. An toàn khi gọi lại (sẽ huỷ và build lại trạng thái).
setListener(listener)Đăng ký CaptchalaListener cho các callback onReady, onSuccess, onFail, onError, onClose.
verify(activity)Mở CAPTCHA trên Activity được chỉ định. Kết quả trả về qua listener.
CaptchalaResultChứa passToken, challengeId, ttl, isOffline, isClientOnly. Gửi passToken về backend của bạn.
CaptchalaClient.destroy()Huỷ singleton (giải phóng WebView, handle native). Gọi từ Activity.onDestroy nếu bạn re-init thường xuyên.

Xác thực phía máy chủ

Chuyển result.passToken (hoặc result.token) tới backend của bạn rồi xác thực qua API CaptchaLa. Tuyệt đối không để lộ X-App-Secret trong mã client.

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>" }

Xem Tài liệu API để biết chi tiết endpoint xác thực và quy trình X-App-Key / X-App-Secret.

Khắc phục sự cố

  • UnsatisfiedLinkError lúc khởi động
    Hãy đảm bảo abiFilters của bạn bao gồm armeabi-v7a, arm64-v8a, x86, x86_64 để mọi thiết bị tìm được thư viện native phù hợp. Xem app/build.gradle trong demo để biết cấu hình chính xác.

  • ProGuard / R8 loại bỏ class SDK trong bản release
    Thêm rule keep cho package SDK trong proguard-rules.pro, ví dụ -keep class la.captcha.sdk.** { *; }-dontwarn la.captcha.sdk.**.

  • minSdkVersion quá thấp
    SDK yêu cầu minSdkVersion 21 (Android 5.0). Giá trị thấp hơn sẽ lỗi khi compile.

  • Lưu lượng HTTP cleartext bị chặn
    Manifest nên giữ android:usesCleartextTraffic="false" (demo cũng làm vậy). Endpoint CaptchaLa chỉ hỗ trợ HTTPS.

Yêu cầu

  • 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