Android SDK
Add Crovly captcha to native Android apps with Kotlin or Java. WebView integration with activity result callbacks.
Installation
Add the dependency to your module's build.gradle.kts:
dependencies {
implementation("com.crovly.captcha:crovly-android:1.0.0")
}Get your site key at app.crovly.com.
XML Layout
<com.crovly.captcha.CrovlyCaptchaView
android:id="@+id/captcha"
android:layout_width="match_parent"
android:layout_height="65dp"
app:siteKey="YOUR_SITE_KEY"
app:theme="auto"
app:size="normal" />Kotlin Usage
class LoginActivity : AppCompatActivity() {
private var token: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
val captcha = findViewById<CrovlyCaptchaView>(R.id.captcha)
captcha.setCallback(object : CrovlyCallback {
override fun onVerify(token: String) {
this@LoginActivity.token = token
submitButton.isEnabled = true
}
override fun onError(code: String, message: String) {
Toast.makeText(this@LoginActivity, "Error: $message", Toast.LENGTH_SHORT).show()
}
override fun onExpire() {
this@LoginActivity.token = null
submitButton.isEnabled = false
}
})
captcha.load()
}
}XML Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
app:siteKey | string | — | Your public site key (required) |
app:theme | enum | auto | light, dark, or auto |
app:size | enum | normal | normal or invisible |
app:lang | string | Auto-detect | Language code (e.g. tr, ar) |
app:apiUrl | string | https://get.crovly.com | Widget script CDN |
Programmatic Setup
val captcha = CrovlyCaptchaView(this).apply {
siteKey = "YOUR_SITE_KEY"
theme = CrovlyTheme.DARK
size = CrovlySize.NORMAL
lang = "tr"
}
captcha.setCallback(object : CrovlyCallback {
override fun onVerify(token: String) {
sendTokenToBackend(token)
}
})
container.addView(captcha)
captcha.load()BottomSheet Dialog
For a modal captcha experience:
val dialog = CrovlyCaptchaDialog.newInstance(
siteKey = "YOUR_SITE_KEY",
theme = CrovlyTheme.AUTO,
size = CrovlySize.NORMAL,
)
dialog.setCallback(object : CrovlyCallback {
override fun onVerify(token: String) {
this@MainActivity.token = token
dialog.dismiss()
}
})
dialog.show(supportFragmentManager, "crovly")Jetpack Compose
Wrap the View in an AndroidView:
@Composable
fun CrovlyCaptchaComposable(
siteKey: String,
onVerify: (String) -> Unit,
) {
AndroidView(
factory = { context ->
CrovlyCaptchaView(context).apply {
this.siteKey = siteKey
this.theme = CrovlyTheme.AUTO
setCallback(object : CrovlyCallback {
override fun onVerify(token: String) {
onVerify(token)
}
})
load()
}
},
modifier = Modifier
.fillMaxWidth()
.height(65.dp)
)
}Java Usage
CrovlyCaptchaView captcha = findViewById(R.id.captcha);
captcha.setCallback(new CrovlyCallback() {
@Override
public void onVerify(@NonNull String token) {
sendTokenToBackend(token);
}
@Override
public void onError(@NonNull String code, @NonNull String message) {
Log.e("Crovly", code + ": " + message);
}
});
captcha.load();Methods
| Method | Returns | Description |
|---|---|---|
load() | void | Load/reload the captcha widget |
reset() | void | Reset the widget for a new verification |
getResponse(callback) | void | Get the current token asynchronously |
Backend Verification
After getting the token, verify it on your server using any of the server-side SDKs:
// Example using OkHttp
val json = JSONObject().apply {
put("token", token)
put("expectedIp", clientIp)
}
val request = Request.Builder()
.url("https://api.crovly.com/verify-token")
.addHeader("Authorization", "Bearer $secretKey")
.post(json.toString().toRequestBody("application/json".toMediaType()))
.build()Requirements
- Android API 24+ (Android 7.0)
- Internet permission (added automatically by the SDK)