Set Up TDLib on Android in 3 Steps

No NDK. No compiling TDLib from C++ source. Prebuilt 4-ABI AARs paired with a lightweight Kotlin Coroutines and Flow wrapper.

Prerequisites:
  • Ensure your app/src/main/AndroidManifest.xml requests network permission:
    <uses-permission android:name="android.permission.INTERNET" />
  • Obtain your api_id and api_hash by creating an application on my.telegram.org. Store these securely in your local.properties or CI environment variables, exposed through BuildConfig.
Step 1 - add the dependencies

Point Gradle at the prebuilt AAR

The core module bundles libtdjson.so for all 4 Android architectures (arm64-v8a, armeabi-v7a, x86_64, and x86). The ktx module provides coroutines and Flow bridges.

1. Enable Maven Central in repository management:

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}

2. Add dependencies to your app module:

// app/build.gradle.kts (Kotlin DSL)
dependencies {
    implementation("io.github.tdlib-android:core:0.1.1")
    implementation("io.github.tdlib-android:ktx:0.1.1")
}

// Or app/build.gradle (Groovy DSL)
// implementation 'io.github.tdlib-android:core:0.1.1'
// implementation 'io.github.tdlib-android:ktx:0.1.1'
APK & App Bundle Size: When shipping as an Android App Bundle (AAB), Google Play serves only the specific native ABI for each target device (~8–10 MB compressed per ABI). Universal APKs with all 4 ABIs bundled weigh ~35 MB uncompressed.

To explicitly filter which architectures are bundled in your APK (for example, releasing separate 64-bit and 32-bit APKs), configure ndk.abiFilters inside defaultConfig:

android {
    defaultConfig {
        ndk {
            abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
        }
    }
}
Step 2 - configure ProGuard / R8

Keep native symbols unobfuscated

TDLib invokes JNI bridge methods and requires reflection over generated data structures. The core AAR embeds consumer rules automatically. If you customize obfuscation in app/proguard-rules.pro, ensure these keep rules are intact:

# Keep TDLib JNI bridge and generated API classes
-keep class org.drinkless.tdlib.** { *; }
-keepclassmembers class org.drinkless.tdlib.** { *; }
-dontwarn org.drinkless.tdlib.**
Step 3 - load native library & initialize

Boot a TdClient & react to updates

When using the ktx module, TdClient initializes internal database directories and manages Kotlin coroutine dispatchers automatically:

// 1. Initialize TdClient (storage path + credentials)
val client = TdClient(
 filesDir = File(context.filesDir, "tdlib").absolutePath,
 apiId = BuildConfig.TELEGRAM_API_ID,
 apiHash = BuildConfig.TELEGRAM_API_HASH,
 verbosityLevel = 1
)
client.init()

// 2. Collect MTProto updates reactively via Flow
CoroutineScope(Dispatchers.IO).launch {
 client.updates.collect { update ->
 when (update) {
 is TdApi.UpdateAuthorizationState -> {
 handleAuthState(client, update.authorizationState)
 }
 is TdApi.UpdateNewMessage -> {
 handleIncomingMessage(update.message)
 }
 }
 }
}

If you use the low-level core module directly, load the native binary via System.loadLibrary("tdjson") and send your initialization parameters when receiving AuthorizationStateWaitTdlibParameters:

// Send parameters on AuthorizationStateWaitTdlibParameters
val parameters = TdApi.SetTdlibParameters().apply {
 useTestDc = false
 databaseDirectory = File(context.filesDir, "tdlib").absolutePath
 filesDirectory = File(context.filesDir, "tdlib/files").absolutePath
 useFileDatabase = true
 useChatInfoDatabase = true
 useMessageDatabase = true
 useSecretChats = false
 apiId = BuildConfig.TELEGRAM_API_ID
 apiHash = BuildConfig.TELEGRAM_API_HASH
 systemLanguageCode = "en"
 deviceModel = android.os.Build.MODEL
 systemVersion = android.os.Build.VERSION.RELEASE
 applicationVersion = "1.0.0"
}
client.send(parameters)
Verification & Architecture Notes

Compatibility & 16KB Page Size Support

Android 15 (API 35) introduces support for devices configured with 16KB memory page sizes. Binaries published in tdlib-android are built with Android NDK 27+ with maximum page size alignment (-Wl,-z,max-page-size=16384), ensuring full forward compatibility across Pixel 8, Pixel 9, and future Android hardware.

  • Supported ABIs: arm64-v8a (modern devices), armeabi-v7a (legacy 32-bit), x86_64 (64-bit emulators), x86 (32-bit emulators).
  • Minimum Android SDK: API 26 (Android 8.0 Oreo).
  • Zero local compilation: Shipped as standard AARs directly through Maven Central.

For complete CI architecture, binary verification scripts, and sample apps, visit the tdlib-android GitHub repository.