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

# Android SDK

> Install and initialize the Sendrealm Android SDK.

Use the Sendrealm Android SDK to receive mobile push notifications in native Kotlin or Java Android apps.

If your app uses React Native, start with [React Native Bare SDK](/sdks/react-native-bare) or [React Native Expo SDK](/sdks/react-native-expo).

## Requirements

* Android API 27 or newer.
* Google Play services on the target device or emulator.
* A Sendrealm app ID from the dashboard.
* Firebase Cloud Messaging configured for the same Android package name.
* `google-services.json` added to your Android app.
* Firebase service account JSON uploaded in Sendrealm.

See [Mobile Push Credentials](/tutorials/mobile-push-credentials) for Firebase setup.

## Install

Add the SDK dependency to your app module:

```kotlin theme={null}
dependencies {
    implementation("com.sendrealm:sendrealm-android:0.1.2")
}
```

Make sure the Google Services Gradle plugin is applied to your Android app if it is not already:

```kotlin theme={null}
plugins {
    id("com.google.gms.google-services")
}
```

## Add `google-services.json`

Download `google-services.json` from Firebase and place it in your app module:

```text theme={null}
app/google-services.json
```

The Firebase Android package name must match your app `applicationId`.

## Initialize

Initialize once during app startup:

```kotlin theme={null}
import android.os.Bundle
import androidx.activity.ComponentActivity
import com.sendrealm.sdk.Sendrealm
import com.sendrealm.sdk.SendrealmConfig

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

        val config = SendrealmConfig()
            .setEnvironment("development")
            .setAutoRequestPermission(false)

        Sendrealm.initialize(
            context = this,
            appId = "YOUR_SENDREALM_APP_ID",
            config = config
        )
    }
}
```

Use `development` for test builds you want to target separately. Omit `setEnvironment` for production.

Most apps should keep `setAutoRequestPermission(false)` and ask for notification permission after an in-app explanation.

## Ask For Permission

Ask for permission from a user action:

```kotlin theme={null}
Sendrealm.requestPermission(this)
```

Check permission state:

```kotlin theme={null}
val allowed = Sendrealm.hasNotificationPermission(this)
```

Android 13 and newer show a runtime notification permission prompt. Android 12 and older do not have a runtime prompt, but users can still disable notifications in system settings.

## Handle Notification Opens

Forward new launch intents to Sendrealm so notification taps can be tracked and routed:

```kotlin theme={null}
override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    setIntent(intent)
    Sendrealm.handleNotificationOpen(intent)
}
```

Configure your Android intent filters for any app links or deep links you want notifications to open.

## Link A Signed-In User

Call `login` after the user signs in:

```kotlin theme={null}
Sendrealm.login("user-123", "user@example.com")
```

Call `logout` when the user signs out:

```kotlin theme={null}
Sendrealm.logout()
```

## Tags

Use tags for app-observed preferences, state, and behavior:

```kotlin theme={null}
Sendrealm.addTags(
    mapOf(
        "plan" to "pro",
        "onboardingComplete" to true
    )
)
```

Do not use SDK tags for authoritative account, billing, security, compliance, or verified profile data. Update those values from your backend.

## Custom Events

Track app events for segmentation, analytics, or automations:

```kotlin theme={null}
Sendrealm.trackEvent(
    "checkout_started",
    mapOf(
        "product_id" to "sku_123",
        "price" to 29
    )
)
```

Use stable event names and avoid sending sensitive data unless your team intentionally wants that data stored in Sendrealm.

## Notification Channels

Android 8 and newer use notification channels for sound, vibration, importance, and visibility. Create separate channel IDs for materially different notification behavior, such as `orders`, `promotions`, or `account_alerts`.

Android may keep the original behavior for a channel after it is created. If you need to change sound or importance in a way users should notice, use a new channel ID.

## Diagnostics

Use diagnostics while testing:

```kotlin theme={null}
val diagnostics = Sendrealm.getDiagnostics(this)
Log.d("Sendrealm", diagnostics.toString())
```

Confirm diagnostics show:

* A device ID.
* Token presence.
* Expected permission status.
* Subscribed state unless the user opted out.
* No unexpected SDK error.

## Troubleshooting

| Symptom                           | What to check                                                                                    |
| --------------------------------- | ------------------------------------------------------------------------------------------------ |
| Token is missing                  | Use a Google Play device or emulator and verify Firebase setup.                                  |
| Notifications do not display      | Check notification permission, Android channel settings, and notification icon resources.        |
| Notifications are delayed         | Check Android power settings, FCM priority, device connectivity, and user notification settings. |
| Sound does not change             | Android may be keeping the original channel behavior. Use a new channel ID.                      |
| Deep link does not open           | Verify the notification URL and Android intent filters.                                          |
| Tags fail with `ContactNotLinked` | Call `login(userId, email)` before setting user tags.                                            |

## Related Pages

* [Mobile Push Credentials](/tutorials/mobile-push-credentials)
* [Send Push Notification API](/api-reference/endpoint/send-push-notification)
* [React Native Bare SDK](/sdks/react-native-bare)
