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.
Before you start
Section titled “Before you start”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.
Install
Section titled “Install”-
Add JitPack to your
settings.gradle.kts:dependencyResolutionManagement {repositories {google()mavenCentral()maven("https://jitpack.io")}} -
Add the SDK to your app module’s
build.gradle.kts:dependencies {implementation("com.github.rnadigital:monita-android-sdk:2.0.1")} -
Sync the project (Sync Now in Android Studio, or
./gradlew build).
Initialize
Section titled “Initialize”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.
Choose an integration mode
Section titled “Choose an integration mode”The SDK sees traffic through OkHttp. There are two ways to connect it, and they can be combined.
Manual interceptor
Section titled “Manual interceptor”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.
Automatic instrumentation
Section titled “Automatic instrumentation”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).
What gets monitored
Section titled “What gets monitored”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’sversionNameplusversionCode, 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.
Consent
Section titled “Consent”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:
IABTCF_TCString(TCF v2)IABGPP_HDR_GppString(GPP)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.
Configuration options
Section titled “Configuration options”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. |
Verify
Section titled “Verify”-
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.
-
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. -
Using automatic instrumentation? Confirm the weave: a built client’s
interceptorslist containsai.monita.sdk.MonitaInterceptor.
Coverage and limitations
Section titled “Coverage and limitations”| 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.
Troubleshooting
Section titled “Troubleshooting”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.