Docs Android

Android documentation

ANDROID

Stream logs, crashes and user feedback from your Android app to your LogWatcher server. Written in Kotlin, callable from Kotlin and Java. Android 4.1+ (minSdk 16). Persistent SQLite queue, crash handler, logcat mirroring.

Getting started

You need an application key. Create an account, add an app in the dashboard, and copy the key shown on its card. Every SDK call is tied to that key.

Install the SDK

The SDK is a standalone Gradle library module (gr.fintechiq.logwatcher). Build the AAR once and drop it into your app — Maven publication is planned.

# build the AAR from the LogWatcher repository
cd source/client-sdks/android/logwatcher-sdk
./gradlew assembleRelease
# → build/outputs/aar/logwatcher-sdk-release.aar

Copy it to app/libs/ and reference it:

// app/build.gradle
dependencies {
    implementation files('libs/logwatcher-sdk-release.aar')
}

The SDK needs the INTERNET permission (already declared in its manifest).

Initialize

Call init() once, in Application.onCreate(). URL overrides must come before init().

// Kotlin — in Application.onCreate()
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        LogWatcher.setApiUrl("https://fintechiq-logwatcher-19133922986.europe-west1.run.app")
        LogWatcher.init(this, "YOUR_APP_KEY", true)  // true = enable crash reporting
    }
}
// Java — the facade is @JvmStatic, so calls are identical
LogWatcher.setApiUrl("https://fintechiq-logwatcher-19133922986.europe-west1.run.app");
LogWatcher.init(this, "YOUR_APP_KEY", true);

The optional fourth argument enableAndroidLogging (default true) mirrors every LogWatcher call to logcat while you develop.

Send logs

One method per level, same shape as android.util.Log. Logs are queued on-device and uploaded in batches; if the network is down they are retried later.

LogWatcher.d("PaymentFlow", "card inserted · reading chip")
LogWatcher.i("PaymentFlow", "auth approved · code 00")
LogWatcher.w("Network", "settle latency 2.1s — retrying")
LogWatcher.e("PaymentFlow", "auth declined · code 05")
LogWatcher.t("Lifecycle", "onResume")   // trace
LogWatcher.f("Watchdog", "unrecoverable state")  // fatal

For full control there is also LogWatcher.log(lineNumber, method, file, level, tag, text).

LevelMethodWire value
Debugd()0
Warningw()1
Errore()2
Tracet()3
Infoi()4
Fatalf()5

The non-sequential wire values are part of the LogWatcher wire protocol — the SDK handles the mapping.

Crash reporting

Pass true as the third argument of init() and the SDK installs an uncaught-exception handler. Crashes are reported with the exception summary and full stack trace, then control is handed to the previous handler. You can also report one explicitly:

LogWatcher.sendCrash("Checkout crashed", stackTraceString)

Issues & user feedback

Report a noteworthy condition as an issue, or collect a message from the user. Each call returns a URL deep-linking to the item in your dashboard.

val url = LogWatcher.sendIssue("Sync failed", "3 retries exhausted on /settle")
LogWatcher.sendUserFeedback("From the merchant", "Receipt printed twice today")

For a ready-made feedback screen, launch the bundled activity:

val intent = LogWatcher.getUserFeedbackActivityIntent(
    context, "Send feedback", "Tell us what happened",
    "Subject", "Send", "Close")
startActivity(intent)

Device key-values

Attach searchable properties to a device — a store number, a merchant id, a build flavour:

LogWatcher.setDeviceString("store", "ATH-0042")
LogWatcher.setDeviceInteger("lane", 2)
LogWatcher.setDeviceBoolean("pilot", true)
LogWatcher.removeDeviceKey("pilot")

Remote device control

On every launch the SDK registers the device and receives its remote flags. From the dashboard you can enable log collection for a single device (a misbehaving terminal) while the rest of the fleet stays quiet — no release, no restart loop. To force collection locally regardless of the remote flag:

LogWatcher.setForceEnabled(true)   // override the remote toggle
LogWatcher.forceSendOnce()          // flush the queue right now

Advanced options

CallWhat it does
setApiUrl(url)Point the SDK at your server. Before init().
setBaseUrl(url)Base URL used to build dashboard deep-links. Before init().
overrideDeviceName(name)Report a custom device name. Before init().
setMaximumLocalStorageSize(bytes)Cap the on-device log queue (default 5 MiB); oldest entries are dropped first.
getDeviceUrl() / getSessionUrl()Dashboard deep-links for this device / session.
enableUIEventLogging(app)Records Activity lifecycle transitions, rendered as TRANSITION rows in the log viewer.
getUserFeedbackActivityIntent(...)Intent for the bundled user-feedback screen.
enableLogcatLogging()Present for API parity; full behaviour ships in a later SDK release.
Ready to see your first remote log?
Create an app, copy its key, and init the SDK.
Get started