ailoha.
Home/ Docs/ Native Android

Manual setup - Native Android

A Kotlin agent that runs inside Android debug builds and exposes Android Views, Jetpack Compose semantics, screenshots, device state, files, preferences, logs, network capture, profiler data, and WebView helpers.

Core artifact com.ailoha:ailoha-android-agent Default port 9233 Compose optional artifact Sample android/samples

Prerequisites

  • An existing Android app using Gradle, Kotlin, or Java.
  • The Ailoha CLI installed: see install instructions.
  • An emulator or physical device with adb available when connecting from the host.

1. Add the packages

Use the real agent only in debug builds and the no-op artifact in release builds:

dependencies {
    debugImplementation("com.ailoha:ailoha-android-agent:$ailohaVersion")
    debugImplementation("com.ailoha:ailoha-android-agent-compose:$ailohaVersion")
    debugImplementation("com.ailoha:ailoha-android-agent-okhttp:$ailohaVersion")
    debugImplementation("com.ailoha:ailoha-android-agent-timber:$ailohaVersion")
    releaseImplementation("com.ailoha:ailoha-android-agent-noop:$ailohaVersion")
}

Preview packages publish to GitHub Packages Maven. Release packages publish to Maven Central once the repository release workflow is configured for signing and Central Portal credentials.

2. Start the agent

Start in debug-only application code. A debug source-set Application class is the safest option because release builds never reference the server artifact:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            AilohaAndroidAgent.start(
                application = this,
                options = AilohaAgentOptions(appName = "My Android App")
            )
        }
    }
}

The server binds to loopback on 9233 and falls back through 9238. It registers the selected port with the Ailoha broker on 19323.

3. Enable Compose semantics (optional)

For Jetpack Compose, install the optional provider after starting the core agent:

if (BuildConfig.DEBUG) {
    AilohaAndroidAgent.start(this)
    AilohaComposeAgent.install()
}

The Compose provider maps semantics nodes into the protocol tree and uses Modifier.testTag("...") as automationId.

4. Add diagnostics adapters (optional)

Android has many logging and HTTP stacks, so generic capture is app opt-in. For OkHttp and Timber:

val client = OkHttpClient.Builder()
    .addInterceptor(AilohaOkHttpInterceptor())
    .build()

Timber.plant(AilohaTimberTree())

Apps can also call AilohaAndroidAgent.recordNetworkRequest(...), recordLog(...), and mark(...) directly.

5. Use stable IDs

For Android Views, resource IDs are stable and become protocol automation IDs. You can also set an explicit Ailoha tag:

binding.loginButton.setAilohaAutomationId("LoginButton")

For Compose:

Button(
    modifier = Modifier.testTag("LoginButton"),
    onClick = ::signIn
) { Text("Sign in") }

6. Run and verify

Launch the app in debug mode, forward the port, then query the agent:

adb forward tcp:9233 tcp:9233
ailoha agent status
ailoha ui tree --depth 2
ailoha ui screenshot --output ./android-shot.png

Limitations

  • Secure storage, BLE, and generic device jobs return explicit unsupported responses unless a future adapter is added.
  • Network and log capture require an adapter or direct calls into the agent API.
  • WebSocket streams are not advertised by the Android agent yet; use the REST log, network, and profiler endpoints.
  • Never enable the agent in production builds. Use debug source sets, debugImplementation, and the no-op release artifact.

What's next