feat: implement background task management for improved streaming continuity
- Integrated BackgroundTasks framework in iOS to manage background processing for audio streams. - Added methods to register, schedule, and handle background tasks, allowing streams to continue for extended periods. - Enhanced the BackgroundStreamingHandler to support background task notifications and keep-alive signals. - Updated Info.plist to permit background task identifiers, ensuring compliance with iOS requirements. - Improved the PersistentStreamingService to handle background task extensions and keep-alive signals effectively, enhancing overall streaming reliability.
This commit is contained in:
@@ -5,7 +5,7 @@ import '../utils/debug_logger.dart';
|
||||
|
||||
/// Handles background streaming continuation for iOS and Android
|
||||
///
|
||||
/// On iOS: Uses background tasks to keep streams alive for ~30 seconds
|
||||
/// On iOS: Uses beginBackgroundTask (~30s) + BGTaskScheduler (~3+ minutes)
|
||||
/// On Android: Uses foreground service notifications
|
||||
class BackgroundStreamingHandler {
|
||||
static const MethodChannel _channel = MethodChannel(
|
||||
@@ -26,6 +26,8 @@ class BackgroundStreamingHandler {
|
||||
// Callbacks for platform-specific events
|
||||
void Function(List<String> streamIds)? onStreamsSuspending;
|
||||
void Function()? onBackgroundTaskExpiring;
|
||||
void Function(List<String> streamIds, int estimatedSeconds)? onBackgroundTaskExtended;
|
||||
void Function()? onBackgroundKeepAlive;
|
||||
bool Function()? shouldContinueInBackground;
|
||||
|
||||
void _setupMethodCallHandler() {
|
||||
@@ -56,6 +58,26 @@ class BackgroundStreamingHandler {
|
||||
DebugLogger.stream('task-expiring', scope: 'background');
|
||||
onBackgroundTaskExpiring?.call();
|
||||
break;
|
||||
|
||||
case 'backgroundTaskExtended':
|
||||
final Map<String, dynamic> args =
|
||||
call.arguments as Map<String, dynamic>;
|
||||
final List<String> streamIds = (args['streamIds'] as List)
|
||||
.cast<String>();
|
||||
final int estimatedTime = args['estimatedTime'] as int;
|
||||
|
||||
DebugLogger.stream(
|
||||
'task-extended',
|
||||
scope: 'background',
|
||||
data: {'count': streamIds.length, 'time': estimatedTime},
|
||||
);
|
||||
onBackgroundTaskExtended?.call(streamIds, estimatedTime);
|
||||
break;
|
||||
|
||||
case 'backgroundKeepAlive':
|
||||
DebugLogger.stream('keepalive-signal', scope: 'background');
|
||||
onBackgroundKeepAlive?.call();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -62,6 +62,28 @@ class PersistentStreamingService with WidgetsBindingObserver {
|
||||
_saveStreamStatesForRecovery();
|
||||
};
|
||||
|
||||
_backgroundHandler.onBackgroundTaskExtended = (streamIds, estimatedSeconds) {
|
||||
DebugLogger.stream(
|
||||
'PersistentStreaming: Background task extended for $estimatedSeconds seconds',
|
||||
);
|
||||
// BGTaskScheduler has given us more time - streams can continue
|
||||
for (final streamId in streamIds) {
|
||||
final metadata = _streamMetadata[streamId];
|
||||
if (metadata != null) {
|
||||
metadata['bgTaskExtended'] = true;
|
||||
metadata['bgTaskExtendedAt'] = DateTime.now();
|
||||
metadata['bgTaskEstimatedTime'] = estimatedSeconds;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_backgroundHandler.onBackgroundKeepAlive = () {
|
||||
DebugLogger.stream('PersistentStreaming: Background keep-alive signal');
|
||||
// BGTaskScheduler is keeping us alive - we can continue streaming
|
||||
_heartbeatTimer?.cancel();
|
||||
_startHeartbeat(); // Restart heartbeat timer
|
||||
};
|
||||
|
||||
_backgroundHandler.shouldContinueInBackground = () {
|
||||
return _activeStreams.isNotEmpty;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user