> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pushctl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Android identity and events

> Associate Android installations with users and handle foreground or opened notifications.

## Associate your user

Call `login` after your own authentication succeeds and Pushctl registration is confirmed. Use a stable, non-secret ID from your backend. The callback runs after the API accepts the association.

```kotlin theme={null}
Pushctl.waitForRegistration { registrationError ->
    if (registrationError != null) {
        Log.e("Pushctl", "Registration failed", registrationError)
        return@waitForRegistration
    }

    Pushctl.login(user.id) { loginError ->
        if (loginError != null) Log.e("Pushctl", "Login failed", loginError)
    }
}
```

Call `logout` when that user signs out:

```kotlin theme={null}
Pushctl.logout { error ->
    if (error != null) Log.e("Pushctl", "Logout failed", error)
}
```

The installation stays subscribed anonymously after a successful logout. Login and logout report an error when the installation is not registered or the API update fails.

## Handle notification interaction

```kotlin theme={null}
val openedListener = PushctlNotificationListener { notification ->
    notification.actionUrl?.let(router::open)
}

Pushctl.addNotificationClickListener(openedListener)
Pushctl.addForegroundNotificationListener { notification ->
    analytics.track("push_foreground", notification.notificationId)
}
```

Remove a retained listener when its owner is destroyed:

```kotlin theme={null}
Pushctl.removeNotificationClickListener(openedListener)
```

## Delivery analytics

The SDK persists events before sending and retries them during later starts, registrations, and events. Deterministic event IDs make these retries safe.

<Note>
  Notification `data` values are strings. Use an application-level schema and parse them defensively.
</Note>
