LogDrop
Sdk

LogDrop Android SDK

The LogDrop Android SDK is distributed via Gradle and integrates into your app using a flexible configuration builder.


1. SDK Installation

1.1. Add the LogDrop Maven repository

In your project-level build.gradle (or settings.gradle for Gradle 8+), make sure the LogDrop repository is included:

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://artifactory.logdrop.io/repository/android-logdrop-sdk/" }
    }
}

If you are using the new Gradle version catalogs / dependencyResolutionManagement, add the maven { ... } block there instead.

1.2. Add the SDK dependency

In your app module build.gradle:
dependencies {
    implementation "io.logdrop:sdk:2.1.8"
}

Replace x.x.x with the latest SDK version.

Sync Gradle after updating the configuration.


2. Initialization

Initialize LogDrop in your Application class.

class LogDropDemoApp : Application() {

    override fun onCreate() {
        super.onCreate()

        // Required for accurate crash reporting and foreground/background tracking
        LogDrop.registerActivityLifecycleCallback(this)

        val config = LogDropConfig.Builder()
            .appId("YOUR_APP_ID")
            .baseUrl("YOUR_BASE_URL") // Optional: for self-hosted LogDrop
            .logcatEnabled(true)
            .build()

        LogDrop.init(this, config)
    }
}

Crash tracking, HTTP logging, and sensitive info filters are resolved and controlled dynamically from the LogDrop backend (Settings -> Remote Config) rather than locally in the config builder.

Optionally, you can refresh the current FCM token after initialization:

FirebaseMessaging.getInstance().token
    .addOnCompleteListener { task ->
        if (!task.isSuccessful) return@addOnCompleteListener
        task.result?.let { LogDrop.onNewFcmPushToken(it) }
    }

3. LogDropConfig Overview

Key configuration fields:
  • appId: String Your LogDrop project Application ID. Required.

  • baseUrl: String? Custom backend URL for on-prem / self-hosted LogDrop deployments.

  • logcatEnabled: Boolean Enables automatic collection of Logcat logs.

  • pushCallbacks: LogDropPushCallbacks? Receives notification received, opened, and silent-push callbacks.

  • pushDeeplinkHandler: LogDropPushDeeplinkHandler? Lets the application take over routing for push actions and deep links.

  • inAppLifecycleCallbacks: LogDropInAppLifecycleCallbacks? Observes in-app popup presentation and dismissal.

  • internalBrowserLifecycleCallbacks: LogDropInternalBrowserLifecycleCallbacks? Observes LogDrop's internal browser lifecycle.

    Use the LogDropConfig.Builder to create the config instance in a safe and fluent way.


4. Crash Tracking (mapping upload)

To get human-readable stack traces, ProGuard/R8 mapping files must be uploaded to LogDrop.

LogDrop provides a Gradle plugin that automates mapping uploads during release builds.

4.1. Add the Gradle plugin dependency

In your project-level build.gradle:
buildscript {
    repositories {
        google()
        mavenCentral()
        maven { url "https://artifactory.logdrop.io/repository/logdrop-gradle-plugin/" }
    }

    dependencies {
        classpath "io.logdrop.gradle:plugin:1.1.0"
    }
}

Replace x.x.x with the latest plugin version.

4.2. Apply the plugin in the app module

In your app module build.gradle (Kotlin DSL or Groovy):

plugins {
    id "com.android.application"
    id "org.jetbrains.kotlin.android"
    id "io.logdrop.gradle.plugin"
}

4.3. Create logdrop-services.json

In the app module root, create a file named logdrop-services.json:

{
  "base_url": "<YOUR_BASE_URL>",
  "projects": {
    "com.yourcompany.yourapp": {
      "app_id": "<YOUR_APP_ID>"
    },
    "com.yourcompany.yourapp.dev": {
      "app_id": "<YOUR_DEV_APP_ID>"
    }
  }
}
  • Keys under projects are your application IDs / namespaces.

  • The plugin automatically selects the correct project and Application ID based on the current variant.

    4.4. ProGuard / R8 configuration

    In your proguard-rules.pro (or equivalent), keep line number and source file attributes:

-keepattributes LineNumberTable,SourceFile
-renamesourcefileattribute SourceFile

This ensures LogDrop can show file names and line numbers in crash reports.


5. Logging Methods

Use the LogDrop logging methods to record events:
LogDrop.e("PaymentActivity", "Payment failed", logFlow)   // Error
LogDrop.w("Network", "Slow network", logFlow)             // Warning
LogDrop.i("Auth", "User logged in", logFlow)              // Info
LogDrop.d("Parser", "Parsing response", logFlow)          // Debug

Logs are stored locally on the device first. To send them to the server, call:

LogDrop.sendLogs()
  • Schedules a background job that runs approximately 60 seconds later.
  • If a job is already scheduled or running, additional calls do not create new jobs.

If your app already handles deep links itself, forward the received intent to LogDrop manually.

Call LogDrop.onNewIntent(...) from the activity that owns the deep link intent-filter.

6.1. Cold Start

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    if (intent?.action == Intent.ACTION_VIEW && intent?.data != null) {
        LogDrop.onNewIntent(this, intent)
    }
}

6.2. App Already Open (singleTop / singleTask)

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    setIntent(intent)

    if (intent.action == Intent.ACTION_VIEW && intent.data != null) {
        LogDrop.onNewIntent(this, intent)
    }
}

Only add this to the activity that actually receives the deep link intent.


7. LogFlow

LogFlow lets you group related logs under a specific business flow or transaction.

val flow = LogFlow(
    name = "SuccessTransaction",
    id = transactionId,
    customAttributes = mapOf(
        "amount" to "149.90",
        "currency" to "TRY"
    )
)

LogDrop.i("TransactionActivity", "Transaction completed successfully.", flow)

In the LogDrop panel you can filter and analyze logs by flowName and flowId.


8. Push Notification Integration

LogDrop supports alert, rich, in-app, deep-link, internal-browser, and silent fetch-logs pushes. Forward messages recognized by LogDrop.isLogDropPush(...) to the SDK from your messaging service.

8.1. Firebase Cloud Messaging (FCM)

Implement a custom FirebaseMessagingService:
class LogDropDemoMessagingService : FirebaseMessagingService() {

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        if (LogDrop.isLogDropPush(remoteMessage.data)) {
            LogDrop.onRemoteMessageReceived(
                context = this,
                data = remoteMessage.data,
                notificationTitle = remoteMessage.notification?.title,
                notificationBody = remoteMessage.notification?.body
            )
        }
    }

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        LogDrop.onNewFcmPushToken(token)
    }
}
  • isLogDropPush(data) Identifies messages owned by LogDrop without intercepting the application's other FCM messages.

  • onRemoteMessageReceived(...) Displays and tracks LogDrop pushes or handles silent fetch-logs commands.

  • onNewFcmPushToken(token: String) Updates the FCM token used by LogDrop.

  • Make sure the service is declared in your AndroidManifest.xml.

    8.2. Show a Pending In-App Push

    When an activity is ready to present UI, ask LogDrop to show any queued in-app popup or internal-browser action:

override fun onResume() {
    super.onResume()
    LogDrop.showPendingPushPopup(this)
}

The method returns LogDropPopupShowResult, which can be used if the application needs to react to whether an item was shown, unavailable, or not pending.

8.3. Huawei Mobile Services (HMS) – optional

If you support Huawei devices without GMS, implement HmsMessageService:

class LogDropDemoHmsMessagingService : HmsMessageService() {

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        LogDrop.onNewHmsPushToken(token)
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        if (LogDrop.isLogDropPush(remoteMessage.dataOfMap)) {
            LogDrop.onRemoteMessageReceived(
                context = this,
                data = remoteMessage.dataOfMap
            )
        }
    }
}
  • onRemoteMessageReceived(...) Handles LogDrop alert and silent pushes via HMS.
  • onNewHmsPushToken(token: String) Updates the HMS push token used by LogDrop.

9. User Identification (UUID Customization)

By default, logs are tied to a device identifier. To associate logs with your own user ID:

LogDrop.userUpdate(userId = "user-1234@example.com")

You can use any stable, unique identifier, such as:

  • Email address

  • Internal customer ID

  • Other application-specific user ID

    All subsequent logs will be associated with this user in the LogDrop panel.


10. Custom Events

Use custom events to track application-specific actions that are not covered by LogDrop's built-in events. Send a stable event name together with optional JSON-compatible properties.

10.1. Track a Custom Event

LogDrop.trackCustomEvent(
    eventName = "purchase_completed",
    properties = mapOf(
        "coupon_code" to "SUMMER10",
        "amount" to 49.9,
        "item_count" to 2,
        "is_first_order" to true
    )
)

Properties are optional. To track an event without properties:

LogDrop.trackCustomEvent(eventName = "onboarding_completed")

Provide only the readable event name and properties. Event and property codes shown in the panel are managed by LogDrop.

10.2. Supported Property Values

Custom properties may contain strings, numbers, booleans, Date values, null, nested maps, collections, and arrays. Map keys must be strings.

LogDrop.trackCustomEvent(
    eventName = "product_viewed",
    properties = mapOf(
        "sku" to "LD-100",
        "viewed_at" to java.util.Date(),
        "product" to mapOf(
            "name" to "LogDrop Hoodie",
            "price" to 79.95
        ),
        "categories" to listOf("merch", "hoodies"),
        "variants" to listOf(
            mapOf("color" to "black", "size" to "M"),
            mapOf("color" to "green", "size" to "L")
        ),
        "campaign" to null
    )
)

Date values are represented as UTC ISO-8601 strings in LogDrop. Nested objects and arrays remain structured values.

10.3. Naming and Property Types

  • Use stable and consistent names. For example, do not alternate between purchase_completed and purchaseCompleted for the same event.
  • Do not put IDs, timestamps, or other dynamic values in the event name. Add them as properties instead.
  • Do not use the name of a LogDrop default event for a custom event.
  • Keep each property's type stable. For example, always send amount as a number rather than sometimes sending a number and sometimes a string.
  • Reusing the same event name updates the same custom event schema. Changing the name creates a different custom event.

If a property is later sent with a different type, LogDrop keeps the event but marks the property as a type conflict in the panel. Type conflict tracking helps find integration mistakes; it should not be used as a replacement for a stable event contract.

10.4. Limits and Validation

  • Event names can contain up to 128 characters.
  • Property names can contain up to 128 characters.
  • One event can contain up to 100 top-level properties.
  • The complete properties JSON can contain up to 16 KB in UTF-8, including property names, primitive values, nested objects, and arrays.
  • Event names and property names cannot be empty.
  • Property values must be JSON-compatible.

If validation fails, the SDK rejects the complete event and writes the reason to the SDK log. Names, properties, and payloads are never silently truncated.

10.5. Panel Behavior

No custom event definition is required before tracking. After the first valid event reaches LogDrop, the Events page shows the event, its generated code, observed properties, property types, and any type conflicts. You can then use the event in event details and Event Analytics funnels.


11. Custom User Attributes

Custom user attributes let you attach stable profile information to the current LogDrop device and use it for segment-based push targeting in the panel. Call the API after LogDrop.init(...) has completed.

11.1. Set or Update Attributes

LogDrop.setCustomAttributes(
    mapOf(
        "plan_type" to "premium",
        "country" to "TR",
        "preferred_language" to "tr"
    )
)

New attributes are merged with the values already stored by the SDK. Sending an existing key replaces its value; other keys remain unchanged. Valid changes are persisted locally and synchronized with LogDrop automatically.

11.2. Remove an Attribute

LogDrop.removeCustomAttribute("plan_type")

Removing a key also synchronizes the deletion with LogDrop, so the old value is no longer available for future segment targeting.

11.3. Limits and Validation

  • A device can have up to 30 custom attributes in total.
  • Keys must contain only letters, numbers, underscores (_), or hyphens (-).
  • Keys can contain up to 64 characters.
  • Values must be non-blank strings containing up to 256 characters.
  • If one entry in a call is invalid, the SDK rejects the complete update.
  • If the merged result would exceed 30 keys, the SDK keeps the previous attribute set unchanged.

Custom user attributes are different from LogFlow.customAttributes. User attributes describe a device for audience targeting, while flow attributes add context only to the logs recorded with that LogFlow.

11.4. Use Attributes in the Panel

After the device synchronizes, open Push Notification → Send Push, select Segment under Recipients, and build a filter with the attribute key. See Segment Targeting with Custom Attributes.


12. Troubleshooting

  • Verify that the logdrop-services.json file exists in the app module and that its projects keys match your application IDs.
  • Make sure the LogDrop Gradle plugin is applied and the repository URL is correct.
  • Confirm that mapping files are being uploaded for release builds (check the Gradle build output).
  • Ensure that LogDrop.registerActivityLifecycleCallback(this) is called before LogDrop.init(...).
  • Check that your FCM/HMS messaging services are correctly registered in AndroidManifest.xml.
  • Confirm that custom event names do not match LogDrop default event names.
  • Check SDK logs when a custom event is missing; invalid names, properties, or oversized payloads are rejected locally.
  • Check SDK logs when custom user attributes are missing; invalid updates and updates exceeding 30 keys are rejected locally.
  • In development, enable verbose logging with:
val config = LogDropConfig.Builder()
    .appId("YOUR_APP_ID")
    .logcatEnabled(true)
    // ...
    .build()

On this page