Android SDK
Integrating Notify Partners push notifications into an Android application — installation via Maven Central, Firebase setup, SDK initialization, and full API reference.
Requirements
- Android 5.0+ (API 21)
- Kotlin 2.x+ or Java 8+
- Firebase project with FCM (Firebase Cloud Messaging) configured
app_idfrom the Notify Partners dashboard
1. Installation
Gradle (Maven Central)
app/build.gradle.kts:
dependencies {
implementation("partners.notify:notify-partners-sdk:1.0.0")
implementation(platform("com.google.firebase:firebase-bom:32.7.0"))
implementation("com.google.firebase:firebase-messaging")
}Maven Central is included by default in new Android projects. If needed, ensure mavenCentral() is in your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}2. Firebase Setup
- Create a project in the Firebase Console
- Add your Android application to the project
- Download
google-services.jsonand place it inapp/ - Add the Google Services plugin:
build.gradle.kts (root):
plugins {
id("com.google.gms.google-services") version "4.4.0" apply false
}app/build.gradle.kts:
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
}3. SDK Initialization
Initialize the SDK in Application.onCreate() — this ensures the SDK is ready before any Activity starts.
Basic
import android.app.Application
import partners.notify.sdk.NotifyPartnersSDK
class YourApplication : Application() {
override fun onCreate() {
super.onCreate()
NotifyPartnersSDK.initialize(
context = this,
appId = "YOUR_APP_ID"
)
}
}With Config Builder
For advanced configuration, use NotifyPartnersConfig.Builder:
import android.app.Application
import android.util.Log
import partners.notify.sdk.NotifyPartnersConfig
import partners.notify.sdk.NotifyPartnersListener
import partners.notify.sdk.NotifyPartnersSDK
class YourApplication : Application() {
override fun onCreate() {
super.onCreate()
val config = NotifyPartnersConfig.Builder("YOUR_APP_ID")
.externalId("user-123")
.debugLogging(BuildConfig.DEBUG)
.listener(object : NotifyPartnersListener {
override fun onInitialized(instanceId: String) {
Log.d("SDK", "Ready: $instanceId")
}
override fun onInitializationFailed(error: Throwable) {
Log.e("SDK", "Init failed", error)
}
override fun onMessageReceived(
msgId: String, title: String, body: String, data: Map<String, String>
) {
Log.d("SDK", "Push received: $title")
}
})
.build()
NotifyPartnersSDK.initialize(this, config)
}
}Don't forget AndroidManifest.xml
Declare your Application class:
<application
android:name=".YourApplication"
...>What Happens During Initialization
- A unique device token is generated (or restored from SharedPreferences) and the device is registered on the server
- The FCM token is requested and device info is sent to the server
- Periodic updates are scheduled via WorkManager
- Lifecycle observer is registered (automatic
onscreen/backgroundevents) - Click interceptor is registered (automatic
clickedevents)
4. That's It — Everything is Automatic
The SDK automatically tracks lifecycle and handles notification clicks. No code in Activity is needed.
- Lifecycle tracking —
ProcessLifecycleOwnersendsonscreen/backgroundevents automatically when the app moves between foreground and background. - Click handling —
ActivityLifecycleCallbacksintercepts notification taps and sendsclickedevents automatically. Duplicate clicks are prevented.
Your Activity can be empty:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Nothing else needed — the SDK handles everything
}
}Deep Link URLs (optional)
If you need to handle the URL from a notification (e.g., for navigation):
import partners.notify.sdk.NotifyPartnersConstants
val url = intent?.getStringExtra(NotifyPartnersConstants.EXTRA_URL)5. Push Notification Handling
The SDK automatically registers NotifyPartnersFirebaseService, which:
- Receives an FCM message — extracts
msg_idfromdata - Sends a
deliveredevent — viaNotifyPartnersSDK.notifyDelivered(msgId)(or direct API call if SDK is not yet initialized) - Calls
NotifyPartnersListener.onMessageReceived— if a listener is set - Displays the notification — with title, body, optional image, and click handling
- On tap — opens the main Activity with
NotifyPartnersConstants.EXTRA_MSG_IDandNotifyPartnersConstants.EXTRA_URLin Intent extras; theclickedevent is sent automatically
Data payload format from the server:
{
"msg_id": "message-uuid",
"title": "Title",
"body": "Notification body",
"image": "https://example.com/image.png",
"url": "https://example.com/action"
}6. Tags and Segmentation
Set tags to segment users:
NotifyPartnersSDK.setTags(mapOf(
"plan" to "premium",
"city" to "moscow",
"interests" to "sports"
))Update the external ID after user login:
NotifyPartnersSDK.setExternalId("user-456")Validation limits:
- Maximum 50 tags per call
- Tag key: maximum 128 characters
- Tag value: maximum 256 characters
externalId: maximum 256 characters- Violations throw
IllegalArgumentException
Persistence: tags and externalId are saved to SharedPreferences and survive process death.
Debouncing: rapid consecutive calls to setTags or setExternalId are coalesced — only the last value is sent to the server.
7. Permissions
The SDK automatically declares the required permissions in its AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />For Android 13+ (API 33), you must request the POST_NOTIFICATIONS permission at runtime:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1)
}API Reference
NotifyPartnersSDK
Kotlin object (singleton). The main entry point for working with the SDK.
object NotifyPartnersSDKinitialize(context, config)
Initialize the SDK with a NotifyPartnersConfig. Call in Application.onCreate().
@JvmStatic
@Synchronized
fun initialize(context: Context, config: NotifyPartnersConfig)Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
context | Context | Yes | Application context |
config | NotifyPartnersConfig | Yes | SDK configuration (see below) |
Protected against double initialization — subsequent calls are ignored.
initialize(context, appId, externalId?)
Convenience overload for simple initialization.
@JvmStatic
@Synchronized
fun initialize(
context: Context,
appId: String,
externalId: String? = null
)Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
context | Context | Yes | Application context |
appId | String | Yes | Application ID from the Notify Partners dashboard |
externalId | String? | No | External user identifier |
setExternalId
Update the external user identifier.
@JvmStatic
fun setExternalId(externalId: String)| Parameter | Type | Required | Description |
|---|---|---|---|
externalId | String | Yes | New external identifier (max 256 characters) |
- Throws
IllegalArgumentExceptionif exceeds 256 characters - If SDK is not yet initialized, the call is silently ignored (validation still runs)
- Saved to SharedPreferences (persists across restarts)
- Debounced — rapid calls are coalesced
setTags
Set tags for user segmentation.
@JvmStatic
fun setTags(tags: Map<String, String>)| Parameter | Type | Required | Description |
|---|---|---|---|
tags | Map<String, String> | Yes | Tags for segmentation (max 50 tags, key max 128, value max 256 chars) |
- Throws
IllegalArgumentExceptionon validation failure - If SDK is not yet initialized, the call is silently ignored (validation still runs)
- Tags are replaced in full (not merged)
- Saved to SharedPreferences (persists across restarts)
- Debounced — rapid calls are coalesced
notifyDelivered
Report that a push notification was delivered. Called automatically by NotifyPartnersFirebaseService.
@JvmStatic
fun notifyDelivered(msgId: String)- Retry policy: EVENT (2 attempts, backoff from 500ms)
- If SDK is not initialized, the call is skipped (a warning is logged)
notifyClicked
Report that a push notification was clicked. Called automatically by the click interceptor.
@JvmStatic
fun notifyClicked(msgId: String)- Retry policy: EVENT (2 attempts, backoff from 500ms)
- If SDK is not initialized, falls back to
sendEventDirectlyusing persisted config from SharedPreferences (also uses EVENT retry policy)
notifyLifecycle
Send a lifecycle event. Called automatically by ProcessLifecycleOwner.
@JvmStatic
fun notifyLifecycle(event: String)| Value | Meaning |
|---|---|
"onscreen" | App moved to foreground |
"background" | App moved to background |
"closed" | Application is closing (optional) |
- Throws
IllegalArgumentExceptionif event is not one of the above values - Retry policy: EVENT (2 attempts, backoff from 500ms)
awaitReady
Suspend until SDK initialization completes.
suspend fun awaitReady(): BooleanReturns true if initialization succeeded, false if it failed. This is a Kotlin-only API (suspend function without @JvmStatic). Java callers should use setListener to observe initialization instead.
lifecycleScope.launch {
val ready = NotifyPartnersSDK.awaitReady()
if (ready) {
// SDK is fully initialized
}
}shutdown
Shut down the SDK, cancelling all pending operations. After calling this, the SDK can be re-initialized with initialize.
@JvmStatic
@Synchronized
fun shutdown()Unregisters lifecycle observer and click interceptor.
isInitialized
@JvmStatic
fun isInitialized(): BooleanReturns true if the SDK has been initialized.
setListener
Set a listener to receive SDK lifecycle callbacks.
@JvmStatic
fun setListener(listener: NotifyPartnersListener?)Pass null to remove the listener. Can also be set via NotifyPartnersConfig.Builder.listener().
NotifyPartnersConfig
SDK configuration. Use Builder for a fluent setup.
data class NotifyPartnersConfig(
val appId: String,
val externalId: String? = null,
val connectTimeoutMs: Long = 10_000,
val readTimeoutMs: Long = 10_000,
val writeTimeoutMs: Long = 10_000,
val debugLogging: Boolean = false,
val notificationChannelName: String = "Notifications",
val listener: NotifyPartnersListener? = null
)| Field | Type | Default | Description |
|---|---|---|---|
appId | String | — | Application ID (required) |
externalId | String? | null | External user identifier |
connectTimeoutMs | Long | 10_000 | HTTP connect timeout (ms) |
readTimeoutMs | Long | 10_000 | HTTP read timeout (ms) |
writeTimeoutMs | Long | 10_000 | HTTP write timeout (ms) |
debugLogging | Boolean | false | Enable verbose HTTP logging |
notificationChannelName | String | "Notifications" | Notification channel display name (Android 8+) |
listener | NotifyPartnersListener? | null | Listener for SDK callbacks |
Builder:
val config = NotifyPartnersConfig.Builder("YOUR_APP_ID")
.externalId("user-123") // String?
.connectTimeoutMs(15_000) // Long
.readTimeoutMs(15_000) // Long
.writeTimeoutMs(15_000) // Long
.debugLogging(true) // Boolean
.notificationChannelName("Alerts") // String
.listener(myListener) // NotifyPartnersListener?
.build()NotifyPartnersListener
Interface for SDK lifecycle callbacks.
interface NotifyPartnersListener {
fun onInitialized(instanceId: String)
fun onInitializationFailed(error: Throwable)
fun onMessageReceived(msgId: String, title: String, body: String, data: Map<String, String>)
}| Callback | When it fires |
|---|---|
onInitialized(instanceId) | SDK registered with server successfully |
onInitializationFailed(error) | All retry attempts failed |
onMessageReceived(msgId, title, body, data) | FCM push message received |
NotifyPartnersConstants
Public constants for Intent extras.
object NotifyPartnersConstants {
const val EXTRA_MSG_ID = "notify_partners_msg_id"
const val EXTRA_URL = "notify_partners_url"
}ProGuard / R8
Consumer rules are included in the SDK AAR and applied automatically. They preserve the public API (NotifyPartnersSDK, NotifyPartnersConfig, NotifyPartnersListener, NotifyPartnersConstants), NotifyPartnersFirebaseService, and kotlinx.serialization data classes.
Web SDK
Integrating Notify Partners push notifications into a web application — installation via npm, Service Worker setup, SDK initialization, and full API reference.
iOS SDK
Integrating Notify Partners push notifications into an iOS application — installation via Swift Package Manager, APNs setup, SDK initialization, and full API reference.