Customization

Display Name Customization

The Stream backend populates two key properties in the VoIP push notification payload that determine the call’s display name:

  • call_display_name: This calculated property evaluates the following custom data fields on the Call object in order of priority:
    • display_name
    • name
    • title
final result = await call.getOrCreate(
          memberIds: memberIds,
          ringing: true,
          custom: {'display_name': 'Stream group call'},
        );

If none of these fields are set, the property defaults to an empty string.

  • created_by_display_name: This property is always populated and contains the name of the user who initiated the call.

By default, the SDK prioritizes call_display_name for the ringing notification display. If this value is empty, it falls back to created_by_display_name.

UI Customization

Android

All Android UI options are configured via AndroidPushConfiguration and passed through pushConfiguration when creating the StreamVideoPushNotificationManager.

StreamVideo(
  ...,
  pushNotificationManagerProvider: StreamVideoPushNotificationManager.create(
    ...,
    pushConfiguration: const StreamVideoPushConfiguration(
      android: AndroidPushConfiguration(
        // Global Android options
        ringtonePath: 'system_ringtone_default',
        defaultAvatar: 'assets/company_logo.png',
        incomingCallNotificationChannelName: 'Incoming Call',
        missedCallNotificationChannelName: 'Missed Call',
        showFullScreenOnLockScreen: true,

        // Incoming call UI
        incomingCallNotification: IncomingCallNotificationParams(
          showCallHandle: true,
          fullScreenShowLogo: false,
          fullScreenBackgroundColor: '#0955fa',
          fullScreenTextColor: '#ffffff',
        ),

        // Missed call notification UI
        missedCallNotification: MissedCallNotificationParams(
          showNotification: true,
          subtitle: 'Missed call',
          showCallbackButton: true,
          callbackText: 'Call back',
        ),
      ),
    ),
  ),
);

Customize Button Text

Use incomingCallNotification.textAccept and incomingCallNotification.textDecline inside AndroidPushConfiguration to set the Accept/Decline labels.

When supported by the device/OS, the SDK renders a system-styled incoming call notification and the OS controls the button labels. Custom button text applies only when we fall back to our custom incoming call notification (older Android versions or certain Samsung devices/cases).
pushConfiguration: const StreamVideoPushConfiguration(
  android: AndroidPushConfiguration(
    incomingCallNotification: IncomingCallNotificationParams(
      textAccept: 'Answer',
      textDecline: 'Reject',
    ),
  ),
),

Customize Full-screen Appearance

When showFullScreenOnLockScreen is set to true the full-screen incoming call activity on the lock screen will be shown while the phone is ringing. On Android 14+ this requires the Full-screen intent permission to be granted at runtime. You can do this by calling ensureFullScreenIntentPermission() method. See the Android Firebase integration guide.

StreamVideoPushNotificationManager.ensureFullScreenIntentPermission();

Use the IncomingCallNotificationParams fields to control the full-screen UI:

  • fullScreenBackgroundColor
  • fullScreenBackgroundUrl
  • fullScreenTextColor
  • fullScreenLogoUrl
  • fullScreenShowLogo
pushConfiguration: const StreamVideoPushConfiguration(
  android: AndroidPushConfiguration(
    incomingCallNotification: IncomingCallNotificationParams(
      fullScreenBackgroundColor: '#101828',
      fullScreenTextColor: '#ffffff',
      fullScreenBackgroundUrl: 'https://cdn.example.com/call/bg.jpg',
      fullScreenLogoUrl: 'https://cdn.example.com/brand/logo.png',
      fullScreenShowLogo: true,
    ),
  ),
),

Both fullScreenBackgroundUrl and fullScreenLogoUrl accept either an http(s) URL or a path to a Flutter asset (for example, assets/call/bg.jpg). If using assets, ensure they are declared under assets: in your pubspec.yaml.

Customize Missed Call Notification

Use missedCallNotification to configure the missed call system notification:

  • subtitle, callbackText, showCallbackButton
  • showNotification (to enable/disable)
pushConfiguration: const StreamVideoPushConfiguration(
  android: AndroidPushConfiguration(
    missedCallNotification: MissedCallNotificationParams(
      subtitle: 'Missed video call',
      callbackText: 'Call back',
      showCallbackButton: true,
      showNotification: true,
    ),
  ),
),

Customize Ringtone

Set a custom ringtone for incoming calls using ringtonePath. Place the audio file in /android/app/src/main/res/raw/.

If not specified, the system default ringtone is used.

pushConfiguration: const StreamVideoPushConfiguration(
  android: AndroidPushConfiguration(
    // File path: /android/app/src/main/res/raw/ringtone_default.mp3
    ringtonePath: 'ringtone_default',
  ),
),

Place the ringtone audio file at /android/app/src/main/res/raw/ringtone_default.mp3 and set ringtonePath to the file name without extension (ringtone_default). Android resolves sounds in res/raw by resource name. Common formats like .mp3, .wav, or .ogg are supported.

Notification channels

  • incomingCallNotificationChannelName sets the user-visible name of the notification channel used for incoming call notifications (Android 8.0+). The SDK creates or reuses this channel. Users can change its behavior (sound, vibration, importance) in system settings.
  • missedCallNotificationChannelName sets the user-visible name of the channel used for missed call notifications.
Changing a channel’s name in code may create a new channel on devices where a channel with the previous name already exists.

iOS CallKit

While Apple’s CallKit framework limits customization options, you can still configure these essential aspects:

  • iconName: Specifies the app icon to display in the CallKit call screen. Ensure your icon is properly prepared and added as described in Apple’s documentation
  • ringtonePath: Adds a custom ringtone by placing your audio file in the root project directory at /ios/Runner/Ringtone.caf. Make sure it’s included in the Copy Bundle Resources section of Build Phases in Xcode.

Handle behavior:

  • The SDK passes the caller’s user id as the CallKit handle by default.
  • We assume the user id is a GUID/UUID-like identifier, so we use the generic handle type and do not display this value in the incoming call UI (the visible name comes from callerName).
  • If your app uses an email or phone number as the user id, consider setting handleType to email or number so CallKit treats it accordingly. Alternatively, enable useComplexHandle to obfuscate the raw value.
StreamVideo(
    ...,
    pushNotificationManagerProvider: StreamVideoPushNotificationManager.create(
        ...,
        pushConfiguration: const StreamVideoPushConfiguration(
          ios: IOSPushConfiguration(
            iconName: 'IconMask',
            ringtonePath: 'system_ringtone_default',
            handleType: 'generic', // 'generic' | 'number' | 'email'
            useComplexHandle: false,
          ),
        ),
    ),
  );
© Getstream.io, Inc. All Rights Reserved.