Android SDK (Kotlin)
Native Android authentication with OAuth 2.0 PKCE, encrypted storage, and biometric login.
Key Features
Requirements
- Android API 24+ (Android 7.0)
- Kotlin 1.8+
- Android Studio Hedgehog+
Installation
Add the dependency to your module-level build.gradle.
// build.gradle.kts (Module)
dependencies {
implementation("com.idenplane:idenplane-android:1.0.0")
}
// settings.gradle.kts — add repository if needed
dependencyResolutionManagement {
repositories {
mavenCentral()
}
} Configuration
Construct an AuthConfig and pass it directly to IdenplaneClient — there is no separate builder.
import com.idenplane.sdk.IdenplaneClient
import com.idenplane.sdk.AuthConfig
val config = AuthConfig(
serverUrl = "https://auth.example.com",
realm = "my-realm",
clientId = "my-android-app",
redirectUri = "myapp://callback",
)
val idenplane = IdenplaneClient(applicationContext, config) Login with PKCE
login() is a suspend function that just launches a Chrome Custom Tab — it does not return the result directly. Complete the flow in your Activity's onNewIntent/onResume.
// Launch login (opens Chrome Custom Tab)
lifecycleScope.launch {
idenplane.login(activity)
}
// In your Activity:
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
lifecycleScope.launch {
val success = idenplane.handleRedirectIntent(intent)
if (success) {
val user = idenplane.getUserInfo()
println("Logged in as ${user.name}")
}
}
} Biometric Authentication
BiometricAuth is a separate class wrapping BiometricPrompt — it is not a method on IdenplaneClient.
import com.idenplane.sdk.BiometricAuth
val biometric = BiometricAuth(activity)
if (biometric.isBiometricAvailable) {
lifecycleScope.launch {
biometric.authenticate(title = "Verify your identity")
// Execution continues here only after successful authentication
val token = idenplane.getAccessToken()
}
} User Info
Retrieve the authenticated user profile. Note: the User model does not include a roles field — only OIDC standard claims.
lifecycleScope.launch {
val user = idenplane.getUserInfo()
println(user.name) // "John Doe"
println(user.email) // "[email protected]"
println(user.preferredUsername)
} Token Management
Tokens are stored in EncryptedSharedPreferences and refreshed automatically before expiry.
// Get the current access token
val token = idenplane.getAccessToken()
// Manual refresh
lifecycleScope.launch {
idenplane.refreshToken()
val newToken = idenplane.getAccessToken()
}
// Check authentication state
if (idenplane.isAuthenticated) { /* ... */ } Logout
Logout clears stored tokens.
lifecycleScope.launch {
idenplane.logout(activity)
println("Logged out")
} Jetpack Compose Integration
The SDK ships dedicated Compose helpers — rememberIdenplaneClient (auto-disposes the client) and collectAuthStateAsState (wraps the authState StateFlow<Boolean>).
import com.idenplane.sdk.rememberIdenplaneClient
import com.idenplane.sdk.collectAuthStateAsState
@Composable
fun AuthScreen(config: AuthConfig) {
val context = LocalContext.current
val idenplane = rememberIdenplaneClient(context, config)
val isAuthenticated by idenplane.collectAuthStateAsState()
val scope = rememberCoroutineScope()
if (isAuthenticated) {
Button(onClick = { scope.launch { idenplane.logout(context as Activity) } }) {
Text("Logout")
}
} else {
Button(onClick = { scope.launch { idenplane.login(context as Activity) } }) {
Text("Sign In")
}
}
}