final result = await call.getOrCreate(
memberIds: memberIds,
ringing: true,
custom: {'display_name': 'Stream group call'},
);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_namenametitle
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:
fullScreenBackgroundColorfullScreenBackgroundUrlfullScreenTextColorfullScreenLogoUrlfullScreenShowLogo
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,showCallbackButtonshowNotification(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
incomingCallNotificationChannelNamesets 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.missedCallNotificationChannelNamesets 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 documentationringtonePath: 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
handleby default. - We assume the user id is a GUID/UUID-like identifier, so we use the
generichandle type and do not display this value in the incoming call UI (the visible name comes fromcallerName). - If your app uses an email or phone number as the user id, consider setting
handleTypetoemailornumberso CallKit treats it accordingly. Alternatively, enableuseComplexHandleto 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,
),
),
),
);