Push Notifications

To receive push notifications, you’ll need to:

  1. Configure your push notification provider in the Stream Dashboard.
  2. Add the client-side integration for the chosen provider in your app.

We support the following providers:

We ship an individual artifact for each provider to make client-side integration quick and simple. See their individual documentation pages linked above for setup details.

Customizing Push Notifications

If you want, you can also customize how push notifications work.

You can customize push notifications in the following ways:

  • Adding an intent-filter: Lets you choose activities that will be invoked when the Push Notification is handled by the SDK
  • Implementing NotificationHandler: Lets you fully customize how notifications are shown and dismissed
  • Extending our DefaultNotificationHandler: Lets you partially customize the behavior or Push Notification received, but reusing some part of our default implementation.

Adding intent filters in your Android Manifest

You need to create the activities that will be called when the push notification is handled by the SDK and declare an intent-filter with the actions they support.

These are the actions that we provide:

  • io.getstream.video.android.action.INCOMING_CALL: Action used to process an incoming call. The Activity that handles this action should show options to accept/reject the call. You can use our RigningCallContent component to build your screen. This screen can be shown when the device is locked, by adding some arguments in the manifest.
  • io.getstream.video.android.action.OUTGOING_CALL: Action used to process an outgoing call. The Activity that handles this action should show options to cancel the call. You can use our RigningCallContent component to build your screen.
  • io.getstream.video.android.action.ACCEPT_CALL: Action used to accept an incoming call. The Activity that handles this action should accept the call and show the call screen. You can use our CallContent component to build your screen.
  • io.getstream.video.android.action.ONGOING_CALL: Action used to get back to an already ongoing call. The Activity that handles this action should show the call screen. You can use our CallContent component to build your screen.
  • io.getstream.video.android.action.LIVE_CALL: Action used to go into a live call. The Activity that handles this action should show the live call screen. You can use our LivestreamPlayer component to build your screen.

These actions need to be included in the AndroidManifest file:

<manifest>
    <application>
        <activity
            android:name=".IncomingCallActivity"
            android:exported="false"
            android:showOnLockScreen="true"
            android:showWhenLocked="true">
            <intent-filter android:priority="1">
                <action android:name="io.getstream.video.android.action.INCOMING_CALL" />
            </intent-filter>
        </activity>
        <activity
            android:name=".OutgoingCallActivity"
            android:exported="false"
            android:showOnLockScreen="true"
            android:showWhenLocked="true">
            <intent-filter android:priority="1">
                <action android:name="io.getstream.video.android.action.OUTGOING_CALL" />
            </intent-filter>
        </activity>

        <activity
            android:name=".AcceptCallActivity"
            android:exported="false">
            <intent-filter android:priority="1">
                <action android:name="io.getstream.video.android.action.ACCEPT_CALL" />
            </intent-filter>
        </activity>

        <activity
            android:name=".CallActivity"
            android:exported="true"
            android:launchMode="singleTask">
            <intent-filter android:priority="1">
                <action android:name="io.getstream.video.android.action.ONGOING_CALL" />
            </intent-filter>
        </activity>

        <activity
            android:name=".LiveCallActivity"
            android:exported="false">
            <intent-filter android:priority="1">
                <action android:name="io.getstream.video.android.action.LIVE_CALL" />
            </intent-filter>
        </activity>
    </application>
</manifest>

You can handle multiple intent-filter within a single Activity if you prefer.

Once you have declared your activities in the manifest, including the intent-filter for the actions defined previously, your activities will be started when a Push Notification arrives to the device. The Intent that your Activity will receive contains the StreamCallId for the call you need to handle. To obtain the StreamCallId we provide an extension function that you can use:

class IncomingCallActivity : AppCompatActivity {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val streamCallId = intent.streamCallId(NotificationHandler.INTENT_EXTRA_CALL_CID)
        [...]
    }
}

Implementing NotificationHandler

The SDK lets you define the theming and behavior of the notification UI that users see after they receive a push notification. To do this, implement the NotificationHandler interface and show your own notification.

class MyNotificationHandler(private val context: Context) : NotificationHandler {
    private val notificationManager: NotificationManager by lazy {
        context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    }

    // Called when a Ringing Call arrives (outgoing or incoming)
    override fun onRingingCall(callId: StreamCallId, callDisplayName: String) {
        val notification = NotificationCompat.Builder(context, notificationChannelId)
            ... // Configure your own notification
            .build()
        notificationManager.notify(notificationId, notification)
    }

    // Called when a Live Call arrives.
    override fun onLiveCall(callId: StreamCallId, callDisplayName: String) {
        val notification = NotificationCompat.Builder(context, notificationChannelId)
            ... // Configure your own notification
            .build()
        notificationManager.notify(notificationId, notification)
    }

    // Called to create the notification for the active call
    override fun getOngoingCallNotification(callId: StreamCallId): Notification? {
        val notification = NotificationCompat.Builder(context, notificationChannelId)
        ... // Configure your own notification
        .build()
        return notification
    }

}

Finally, pass as the NotificationHandler implementation to the StreamVideoBuilder when initializing the Stream Android SDK:

val notificationHandler = MyNotificationHandler(context)
val notificationConfig = NotificationConfig(
    pushDeviceGenerators = listOf(
        // PushDeviceGenerator
    ),
    notificationHandler = notificationHandler
)

StreamVideoBuilder(
    context = context,
    user = user,
    token = token,
    apiKey = apiKey,
    notificationConfig = notificationConfig,
).build()

Extending DefaultNotificationHandler

Stream Video SDK uses a default implementation of NotificationHandler that searches in the application manifest for activities that handle the actions that we detailed previously. If you want to maintain the default behavior and UI for some notifications but modify others, you can extend the DefaultNotificationHandler open class and override the behavior of the desired type of notification.

class MyNotificationHandler(application: Application) : DefaultNotificationHandler(application) {

    // Override this method if you want a custom behavior for Ringing call notifications
    override fun onRingingCall(callId: StreamCallId, callDisplayName: String) {
        [...]
    }

    // Override this method if you want a custom behavior for default notifications
    override fun onNotification(callId: StreamCallId, callDisplayName: String) {
        [...]
    }

    // Override this method if you want a custom behavior for Live Call notifications
    override fun onLiveCall(callId: StreamCallId, callDisplayName: String) {
        [...]
    }

    // Override this method if you want a custom notification for ongoing calls
    override fun getOngoingCallNotification(callId: StreamCallId): Notification? {
        [...]
    }
}

Handling Push Notification Permissions

Starting from Android API level 33, all apps need to request permissions to be able to show notifications to the user. When you integrate Stream Push Notification, our SDK will request permission to post notification whenever it is needed. If you want to configure this behavior, you can configure it within the NotificationConfig class.

val notificationConfig = NotificationConfig(
    pushDeviceGenerators = listOf(
        // PushDeviceGenerator
    ),
    notificationHandler = notificationHandler,
    // This lambda will be called to check if permission needs to be requesteds by the SDK or not.
    requestPermissionOnAppLaunch = { true }
)
© Getstream.io, Inc. All Rights Reserved.