onecxi_flutter_sdk 1.2.0
onecxi_flutter_sdk: ^1.2.0 copied to clipboard
A Flutter SDK for OneCxi calling functionality with WebSocket and VoIP support
Changelog #
All notable changes to the OneCxi Flutter SDK will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.2.0 - 2026-06-29 #
Added #
- Native incoming-call flow (Android). Incoming calls are now owned by the native
OneCxiCallService, which manages the full call lifecycle (foreground notification, call screen, accept/decline, teardown) independently of the Flutter isolate — so calls behave correctly in background and killed states. initialize(autoStartOnBoot: ...). Hosts can opt in to the legacyflutter_background_serviceboot-restart behavior. Defaults tofalse; on Android the nativeOneCxiCallServicehandles call lifecycle, so boot restart is not required.- Full-screen-intent helpers.
canUseFullScreenIntent()andensureFullScreenIntentPermission()let hosts check and request the Android 14+ full-screen-intent permission needed to show the call screen over the lock screen. resumeAcceptedCallIfAny(). On cold start, resumes a call that was accepted from a native/CallKit UI before the Flutter engine was ready, so an accepted call is not dropped.- Integration guides. Added Android and iOS incoming-call integration guides under
docs/(INCOMING_CALL_INTEGRATION.md,INCOMING_CALL_INTEGRATION_IOS.md).
Fixed #
- CallKit / native handover. CallKit UI is now dismissed once the native service takes ownership of the call, and CallKit "ended" events are ignored while the native service owns the call lifecycle — preventing premature teardown.
1.1.3 - 2026-06-16 #
Fixed #
- Android — SDK no longer clears the host app's notifications.
OneCxiCallService.dismissFCMNotifications()previously enumeratedactiveNotificationsand cancelled every notification except its own, and swept notification IDs1000..1020. It now cancels only the SDK's own incoming-call notification IDs (1001/1002/1003, via the newSDK_INCOMING_CALL_NOTIFICATION_IDSconstant) and never touches notifications it didn't post. - Call UI now tears down when the call ends remotely (agent / backend hangup). Two root causes were fixed:
- Native WebSocket path (Android inbound/outbound):
NativeWebSocketClientonly recognized an end event inside specifictypebranches, so a backend end message with a differenttypewas ignored and the call never ended. The end signal (End/Ended/stop/close_connection/Disconnected) is now detected regardless oftype, matching the Dart side. On detection the call tears down fully — native call screen closes, foreground notification is removed, and Flutter is notified to dismiss the CallKit UI. - Dart WebSocket path (iOS / app-to-app): a remote end only re-emitted the current call status (leaving
isCallOngoingtrue). It now routes through the full call-end teardown (dismiss CallKit UI + reset state) via a newAudioHelper.onRemoteCallEndedcallback.
- Native WebSocket path (Android inbound/outbound):
- Android — reliable call-end teardown on Android 14+ / OEM ROMs. The internal
CALL_EVENTandCLOSE_CALL_SCREENbroadcasts are now explicit (setPackage), so they are reliably delivered to the plugin and the call screen on ROMs that drop implicit broadcasts. The native call screen also self-closes within ~1s if the call is no longer active, as a fallback if a broadcast is ever dropped.
Changed #
- Android — quieter logs by default. Routine native plugin logs are now gated behind the SDK verbose flag (off by default) instead of always printing to
System.out. Enable withinitialize(verboseLogs: true)orsetOneCxiVerboseLogs(true)(thesetVerboseLogsmethod channel is now handled on Android). Errors and warnings still always log.
1.1.2+2 - 2026-05-23 #
Fixed #
- Android
compileDebugKotlinfailure on 1.1.2+1: Removed duplicateKeyguardManagerimport inCallScreenActivity.kt(accidental duplicate introduced in 1.1.2+1).
Changed #
- Android build: Kotlin
2.3.10and Android Gradle Plugin8.11.1(was1.7.10/7.3.0), JVM target 11 — compatible with current Flutter/Android host projects.
1.1.2+1 - 2026-05-23 #
Fixed #
- Android outbound calls: Production DID
90103and correct WebSocket routing when FCM sends invalidcallFrom/callTo.stopDartAudioOnly()prevents accidental call teardown on accept (no spurious/api/call-end403). - Android remote hangup: Native
onCallEnded/onCallDisconnected, WebSocketEnded, and FCMagent_disconnect/event=endnow propagate to Flutter for UI and notification cleanup when the agent disposes the call. - Android ghost “OneCxi Call Active” notifications: Native
OneCxiCallServiceis the sole ongoing-call foreground notification owner on Android;CallBackgroundServiceno longer starts duplicateflutter_background_serviceFGS. Stale notification taps close safely;cleanupStaleCallStateruns on SDK init. - Android
MissingForegroundServiceTypeException: SDK library manifest mergesBackgroundServicewithforegroundServiceType="phoneCall|microphone"so host apps inherit the fix automatically.
Changed #
- Example app aligned to production cloudagent endpoints and DID
90103.
1.1.1+1 - 2026-04-29 #
Changed #
- Background service (
CallBackgroundService): setautoStartOnBoot: falseso the call foreground service does not auto-start on device boot (only starts when a call begins).
1.1.0+1 - 2026-04-09 #
Pub.dev second release (follows 1.0.0+1). Summary of changes shipped in this codebase:
Added / changed #
- Production defaults in
SdkConfig: WebSocketwss://web-stream.cloudagent.ozonetel.com/, REST basehttps://streamingapi.cloudagent.ozonetel.com(override withinitialize(serverName: …)if your API host differs). - Session correlation: push / FCM
callIdused as WebSocketucidon iOS (Dart) and Android native service when present, so outbound media can attach to the server call. - Android native audio:
AudioManager.MODE_IN_COMMUNICATIONset duringAudioTrackinitialization (NativeAudioHelper). - Android native WebSocket: after connect, mirrors Dart handshake —
sendReadyMessage,sendAudioFormatMessage,sendRequestIncomingAudio(timed), outboundsendAudioRequestMessage+startPeriodicAudioRequests. - HTTP call-end: uses REST origin from
initialize()serverNamewhen set, elseSdkConfig.baseUrl. - Example app:
AppConfigserver / registration URLs aligned to cloudagent hosts.
Fixed #
- UCID:
webSocketInitializeno longer overwrites_ucidwhen already set (e.g. from pushcallId).
Integrator notes #
- Confirm API keys and
serverNamefor your environment; defaults target Ozonetel cloudagent production. - Remove or ignore duplicate sources under
android/.../com/onecxi/flutter/sdk/if present; the plugin usescom.onecxi.flutter_sdk.
1.0.0+1 2025-10-XX #
Added #
- Initial release of OneCxi Flutter SDK
- Support for inbound, outbound, and app-to-app calls
- Real-time audio streaming via WebSocket
- CallKit integration for iOS
- Native foreground service for Android
- Push notification support (VoIP for iOS, FCM for Android)
- Call persistence when app is killed
- Lock screen calling interface
- Call controls (mute, hold, speaker, DTMF)
- Comprehensive error handling
- Detailed logging
1.1.0 - 2025-10-15 #
Added 🎉 #
Call Persistence
- Android: Native foreground service keeps calls alive when app is killed
- iOS: Background service with CallKit ensures call persistence
- Automatic UI synchronization when app is reopened during an active call
- Call timer resumes correctly from native call duration
getNativeCallStatus()method to retrieve active call informationisCallActive()method to check call status from native layerforceEndCall()method for cleanup operations
Lock Screen Calling
- Android: Native lock screen UI with accept/decline actions
- iOS: Full CallKit integration with native lock screen interface
- Works seamlessly with device lock/unlock
- Automatic transition between lock screen and in-app UI
showWhenLockedandturnScreenOnsupport for Android MainActivity
Enhanced App-to-App Calls
- Cross-platform: Android ↔ iOS app-to-app calls now fully supported
- Smart WebSocket: Uses Dart WebSocket for app-to-app (better backend compatibility)
- Native WebSocket: Uses native service for inbound/outbound (better persistence)
- Automatic call decline API integration with backend
- Proper WebSocket header configuration for app-to-app calls
UI Synchronization
- App lifecycle monitoring for accurate call status
- Native-to-Flutter state synchronization
- Proper cleanup of UI resources
- Call timer stops and resets properly when call ends
refreshCallStatus()method for manual sync
Changed 🔄 #
WebSocket Management
- App-to-app calls now use Dart WebSocket instead of native (resolves backend compatibility)
- Inbound/outbound calls continue using native WebSocket for persistence
- Improved WebSocket connection handling for different call types
Call Status Tracking
- Android: Dynamic call status from
OneCxiCallServicecompanion object - iOS: Call state persisted in UserDefaults for cross-session tracking
- Enhanced
getNativeCallStatuswith call type, DID, registered number, and duration
Decline API
- Implemented decline API integration with backend
- Uses specific long API key for decline requests
- Sends proper parameters: mobileNO, event, callType, timestamp
- Handles 403 responses as expected behavior for unanswered calls
Fixed 🐛 #
Call Timer Issues
- Fixed timer not stopping when call ends
- Fixed timer not resetting to 00:00 after call
- Fixed timer not starting correctly when app is reopened
- Fixed timer synchronization with native call duration
UI Synchronization
- Fixed call active status not updating properly
- Fixed UI not syncing when app resumes from background
- Fixed dual screens appearing on Android (native + Flutter)
- Removed automatic app launch, rely on user interaction with notification
App-to-App Calls
- Fixed Android → iOS app-to-app calls not connecting
- Fixed WebSocket
EOFExceptionfor app-to-app calls - Fixed incorrect DID in native call status for app-to-app
- Fixed wrong x-did header for app-to-app calls
Native Service
- Fixed Android foreground service notification management
- Fixed call state not clearing properly on end
- Fixed broadcast receiver not being registered correctly
- Fixed iOS call state not persisting across app restarts
Technical Details 🔧 #
Android Native Service
// New foreground service implementation
class OneCxiCallService : Service() {
// Keeps calls alive when app is killed
// Manages notification and wake lock
// Handles WebSocket connection
}
iOS Call State Tracking
// Call state persistence
UserDefaults.standard.set(callState, forKey: "OneCxi_CallActive")
// Retrieved on app restart for UI sync
Smart WebSocket Selection
// App-to-app: Dart WebSocket
if (Platform.isAndroid && callType == 'app_to_app') {
useFlutterAudioHelper();
}
// Inbound/Outbound: Native WebSocket
else if (Platform.isAndroid) {
useNativeService();
}
Migration Guide 📝 #
From v1.0.0 to v1.1.0:
- Update Android Permissions:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
- Update MainActivity (Android):
<activity
android:name=".MainActivity"
android:showWhenLocked="true"
android:turnScreenOn="true"
...>
</activity>
- Implement Lifecycle Monitoring:
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_sdk.refreshCallStatus();
}
}
}
No breaking changes! All existing code continues to work.
1.0.0 - 2025-09-01 #
Added #
- Initial release of OneCxi Flutter SDK
- Support for inbound, outbound, and app-to-app calls
- Real-time audio streaming via WebSocket
- CallKit integration for iOS
- ConnectionService integration for Android
- Push notification support (VoIP for iOS, FCM for Android)
- User registration system
- Call controls (mute, hold, speaker, DTMF)
- Comprehensive error handling
- Detailed logging
Features #
- Multiple call types support
- Cross-platform compatibility (iOS & Android)
- Native UI integration
- Audio recording and playback
- WebSocket communication
- Permission management
- Call state management
Release Notes #
v1.1.0 - Major Update ✨ #
This release brings significant improvements to call reliability and user experience:
Key Highlights:
- 📱 Calls now persist when app is killed (both iOS and Android)
- 🔒 Native lock screen calling interface
- 🔄 Cross-platform app-to-app calls work seamlessly
- 🎯 Improved UI synchronization and state management
What This Means for Users:
- No dropped calls when app is closed
- Professional calling experience on lock screen
- Reliable app-to-app communication across platforms
- Smooth UI updates and timer accuracy
For Developers:
- Easy migration with no breaking changes
- Better debugging with enhanced logging
- Improved error handling and recovery
- Production-ready reliability
Testing Checklist for v1.1.0: #
- ✅ Call persistence when app is killed (Android)
- ✅ Call persistence when app is killed (iOS)
- ✅ Lock screen calling (Android)
- ✅ Lock screen calling (iOS)
- ✅ App-to-app calls (Android → iOS)
- ✅ App-to-app calls (iOS → Android)
- ✅ UI timer synchronization
- ✅ Call status sync on app resume
- ✅ Decline API integration
- ✅ Cross-platform compatibility
Upgrade Path #
From 1.0.0 to 1.1.0 #
- Difficulty: Easy
- Breaking Changes: None
- Estimated Time: 15 minutes
- Required Changes: Add new permissions, update MainActivity (Android)
- Optional Changes: Implement lifecycle monitoring for better UX
From 0.9.x to 1.1.0 #
- Difficulty: Medium
- Breaking Changes: Yes (removed shared_preferences dependency)
- Estimated Time: 30 minutes
- Required Changes: Update dependencies, update error handling, migrate storage
Support #
For issues, questions, or feedback regarding this release:
- Check the Integration Guide
- Review the Troubleshooting section
- Contact support with detailed logs and reproduction steps
Last Updated: April 29, 2026
Current Version: 1.1.1+1