import 'package:stream_video_flutter/stream_video_flutter.dart';
bool? _microphoneEnabledBeforeInterruption;
void _handleMobileAudioInterruptions() {
if (!CurrentPlatform.isMobile) return;
RtcMediaDeviceNotifier.instance.handleCallInterruptionCallbacks(
onInterruptionStart: () {
// Mute the microphone when the interruption starts
final call = StreamVideo.instance.activeCall;
_microphoneEnabledBeforeInterruption =
call?.state.value.localParticipant?.isAudioEnabled;
call?.setMicrophoneEnabled(enabled: false);
},
onInterruptionEnd: () {
// Unmute the microphone when the interruption ends
if (_microphoneEnabledBeforeInterruption == true) {
StreamVideo.instance.activeCall?.setMicrophoneEnabled(enabled: true);
}
_microphoneEnabledBeforeInterruption = null;
},
androidInterruptionSource: AndroidInterruptionSource.audioFocusAndTelephony,
);
}Handling System Audio Interruptions
Audio interruptions are a common occurrence on mobile devices that can disrupt ongoing video calls. The Stream Video Flutter SDK provides built-in support for handling these interruptions gracefully, allowing you to maintain a smooth user experience even when external audio events occur.
What are Audio Interruptions?
Audio interruptions happen when the system or other applications take over the audio session, temporarily pausing or stopping your app’s audio. Common examples include:
iOS Interruptions
- Incoming phone calls
- Siri activation
- Alarm or timer sounds
- Audio from other apps taking over (e.g., voice memo, navigation apps)
Android Interruptions
The interruption sources depend on the configured AndroidInterruptionSource:
With Audio Focus:
- Other media apps interrupting (e.g., Spotify, YouTube)
- Assistant voice prompts (e.g., Google Assistant)
- Alarms and notifications
With Telephony:
- Phone calls (requires
READ_PHONE_STATEpermission)
Basic Implementation
The SDK provides the handleCallInterruptionCallbacks method through RtcMediaDeviceNotifier to manage audio interruptions.
In this example, we disable the microphone during an interruption:
When multiple active calls are enabled, use StreamVideo.instance.activeCalls instead.
In this example, we mute audio playout during a phone call:
import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc;
import 'package:stream_video_flutter/stream_video_flutter.dart';
void _handleMobileAudioInterruptions() {
if (!CurrentPlatform.isMobile) return;
RtcMediaDeviceNotifier.instance.handleCallInterruptionCallbacks(
onInterruptionStart: () {
rtc.Helper.pauseAudioPlayout();
},
onInterruptionEnd: () {
rtc.Helper.resumeAudioPlayout();
},
androidInterruptionSource: AndroidInterruptionSource.telephonyOnly,
);
}On Android, audio focus may not be restored automatically. To ensure you receive onInterruptionEnd, explicitly call rtc.Helper.resumeAudioPlayout(); (for example, when the app resumes from background).
Method Parameters
handleCallInterruptionCallbacks
Future<void> handleCallInterruptionCallbacks({
void Function()? onInterruptionStart,
void Function()? onInterruptionEnd,
AndroidInterruptionSource androidInterruptionSource =
AndroidInterruptionSource.audioFocusAndTelephony,
})Parameters:
onInterruptionStart: Callback function executed when an audio interruption startsonInterruptionEnd: Callback function executed when an audio interruption endsandroidInterruptionSource: Specifies which interruption sources to monitor on Android
On Android, you can filter interruptions for audio and/or telephony; on iOS, all interruptions are enabled.
Android Interruption Sources
enum AndroidInterruptionSource {
audioFocusOnly, // Monitor audio focus changes only
telephonyOnly, // Monitor phone calls only
audioFocusAndTelephony, // Monitor both (default)
}Platform Setup
iOS
No additional configuration is required for iOS. The SDK integrates with the system audio session and handles interruption events for you.
Android Permissions
To handle phone call interruptions on Android, add the following permissions to your android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>Runtime Permission Request
Request the phone permission at runtime for Android:
import 'package:permission_handler/permission_handler.dart';
void _requestPermissions() async {
if (CurrentPlatform.isAndroid) {
await Permission.phone.request();
}
}Best Practices
1. Initialize Early
Set up interruption handling as early as possible in your app lifecycle:
@override
void initState() {
super.initState();
_handleMobileAudioInterruptions();
}2. Platform Check
Always check if the platform is mobile before setting up interruption handling:
void _setupInterruptions() {
if (!CurrentPlatform.isMobile) return;
// Setup interruption handling
}3. Graceful Degradation
Handle cases where permissions might not be granted:
void _setupWithPermissionCheck() async {
if (CurrentPlatform.isAndroid) {
final phonePermission = await Permission.phone.status;
if (phonePermission.isDenied) {
// Handle telephony interruptions only if permission is granted
await Permission.phone.request();
}
}
_handleMobileAudioInterruptions();
}4. Explain Permissions
Requesting low‑level permissions such as READ_PHONE_STATE can worry users. Onboard users first and explain why the permission is needed before requesting it.