Skip to content

Android SDK

The Monita Android SDK observes the vendor network calls your app already makes, matches them against your property’s vendor configuration, and streams them to the same dashboards, detectors and alerts as your web traffic. Monitoring is passive: the SDK never blocks, mutates, re-issues or consumes a request or response, so your app’s networking behaves exactly as if the SDK were not there.

Version 2.0 monitors any vendor you configure on the property, the same catalog as web monitoring: Firebase, Meta, Google Ads, Adobe, AppsFlyer, Adjust, Branch, Amplitude, Mixpanel, Segment, Braze and any custom vendor whose request URL you know.

Create a property with source type Mobile app (or reuse an existing property if you want web and app traffic together), configure your vendors, and copy the SDK token from Manage → Installation guide. See the Monita-side setup for vendor configuration.

Requirements: minSdk 23 (Android 6.0) or later and OkHttp 4.x.

  1. Add JitPack to your settings.gradle.kts:

    dependencyResolutionManagement {
    repositories {
    google()
    mavenCentral()
    maven("https://jitpack.io")
    }
    }
  2. Add the SDK to your app module’s build.gradle.kts:

    dependencies {
    implementation("com.github.rnadigital:monita-android-sdk:2.0.1")
    }
  3. Sync the project (Sync Now in Android Studio, or ./gradlew build).

Initialize the SDK in your Application.onCreate, before any vendor SDK starts sending, so launch-time traffic is observed:

import ai.monita.sdk.Monita
Monita.initialize(context, token = "dom_xxxxxxxxxxxxxxxxxxxxxxxx")

Or with options:

Monita.initialize(context, MonitaConfig.Builder("dom_...").debugLogging(false).build())

Prefer keeping the token out of code? Add it as manifest meta-data and the SDK initializes itself at app startup:

<application>
<meta-data
android:name="ai.monita.sdk.TOKEN"
android:value="dom_xxxxxxxxxxxxxxxxxxxxxxxx" />
</application>

The token identifies the property only. It is a public identifier, not a secret.

The SDK sees traffic through OkHttp. There are two ways to connect it, and they can be combined.

Add MonitaInterceptor to any OkHttp client you build yourself:

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

The interceptor sees the request, the response status and timing. It is safe to add before Monita.initialize runs; it passes traffic through untouched until the SDK is ready. This mode covers every client you construct, but not clients built inside third-party vendor SDKs.

Most vendor SDKs (Firebase, Meta, AppsFlyer, Adjust, Branch and others) build their own OkHttp clients internally, so you cannot add an interceptor by hand. The optional companion build plugin weaves client construction at compile time so every OkHttp client in the app, including clients built inside third-party libraries that use unshaded OkHttp, receives the Monita interceptor automatically.

In your app module:

plugins {
id("com.android.application")
id("net.bytebuddy.byte-buddy-gradle-plugin") version "1.15.11"
}
dependencies {
implementation("com.github.rnadigital:monita-android-sdk:2.0.1")
byteBuddy("com.github.rnadigital:monita-android-sdk-adaptor:2.0.1")
}

The byteBuddy dependency is a compile-time transformation only; it adds nothing to your APK, and the woven code is exception contained, so it can never affect your app’s client construction. Clients built before Monita.initialize runs are left untouched, so initialize early (manifest meta-data auto-init, or first thing in Application.onCreate).

When a request through a connected client matches a configured vendor pattern, the SDK snapshots the URL, method, query parameters and request body, extracts the event name using your property’s event mapping, applies your filters, strips your excluded parameters, and queues the event for delivery.

  • Vendor changes apply remotely. Adding, editing or removing vendors on the property takes effect on devices at the next configuration refresh, with no app release.
  • Delivery is store and forward. Events are batched, persisted on the device and uploaded once the network is reachable, so offline sessions arrive after the next launch with connectivity.
  • Batches carry the app version. Every batch includes av, your app’s versionName plus versionCode, so events from different builds stay distinguishable while you debug a rollout.
  • Manual events. With manual monitoring enabled on the property, Monita.send(vendor, event, data) reports events the SDK cannot observe on the network, such as activity inside a WebView.

Use Monita.setCustomerId(id), Monita.setSessionId(id) and Monita.setScreen(name) to join app events with your web and server-side traffic and to attribute events to screens.

The SDK does not collect consent itself. It reports the consent state your CMP already manages, so monitored traffic carries the same consent context as your tags and feeds consent posture.

By default the SDK reads the IAB standard strings that consent management platforms write to the default SharedPreferences, in this priority order:

  1. IABTCF_TCString (TCF v2)
  2. IABGPP_HDR_GppString (GPP)
  3. IABUSPrivacy_String (US Privacy)

The value is re-read for every upload, so CMP updates propagate without any wiring. To override auto-detection, call Monita.setConsent(consent) with an explicit string, or Monita.setConsentProvider { ... } for a dynamic source.

The SDK keeps monitoring regardless of consent state by default, matching the web script, because tag monitoring is typically run as a compliance measurement function. If your policy requires gating on consent, wire your CMP decision into the event filter:

Monita.setEventFilter { payload -> myCmp.isMonitoringAllowed() }

Returning false drops the event before it is queued or sent.

MonitaConfig.Builder accepts full-URL overrides for customers who route traffic through their own hosts, such as a reverse proxy:

Option Default Description
collectEndpoint(url) https://collect.monita.ai/api/v1 Where captured events are delivered.
configEndpoint(url) Derived from the token Where the property’s vendor configuration is fetched from.
debugLogging(enabled) false Verbose logging and unbatched delivery.
  1. Open Monitor → Realtime in the app, select the property and press Live. Fire a monitored vendor event (for example a Firebase log event) in your app: the payloads arrive within seconds, so you can confirm capture, event names and parameters as you tap through screens. Once a bundle id is set on the property, your app’s icon appears alongside its events. See the Realtime view for everything the stream shows.

  2. Prefer logs? Enable debug logging during rollout:

    Monita.setDebugLogging(true)

    Watch Logcat with the tag Monita: you should see the configuration load, each capture decision, and uploads returning 204. Debug mode also ships every event immediately in its own POST, so nothing waits on batching. Disable it for release.

  3. Using automatic instrumentation? Confirm the weave: a built client’s interceptors list contains ai.monita.sdk.MonitaInterceptor.

Traffic Covered
OkHttp clients with MonitaInterceptor added Yes
OkHttp clients built inside third-party SDKs (unshaded OkHttp, with the instrumentation plugin) Yes
Firebase, Meta, AppsFlyer, Adjust, Branch and other vendor SDKs that use unshaded OkHttp Yes, with the instrumentation plugin
HttpURLConnection traffic No
Cronet traffic No
WebView traffic No
SDKs that shade or embed a renamed copy of OkHttp No
Raw sockets, gRPC over its own transport No
Response bodies Never read, by design

Request bodies are captured only when they are replayable and textual, up to 64KB; larger or binary bodies contribute URL parameters only. Captured parameters are capped at 100 per event and pass your property’s exclusion rules before leaving the device. The SDK generates its own visitor and session identifiers; it never reads the advertising ID, fingerprints the device, or harvests credentials. ProGuard and R8 rules ship inside the library, so no extra keep rules are needed.

No events arrive. Check the token, then enable Monita.setDebugLogging(true) and watch Logcat with the tag Monita. Until the first successful configuration fetch, monitoring stays off; if the configuration never loads, the property may be paused or removed, or the config endpoint is unreachable from the device.

Vendor traffic is not detected. Confirm the vendor’s URL patterns match the request URLs and check the coverage table above. Traffic that does not go through OkHttp is not visible to the SDK, and third-party SDK clients need the instrumentation plugin.

Events are captured but arrive late. Delivery is store and forward, so offline sessions arrive after the next launch with connectivity. Monita.flush() forces an immediate attempt.

Monitoring stopped by itself. A paused or removed property disables capture at the next configuration refresh, and the SDK turns itself off for the rest of the process if it captures an unusually high volume in a short window, which usually means a vendor URL pattern is far too broad. Both are visible in debug logs.

If you are stuck, walk through Deployment troubleshooting or contact support.