onecxi_flutter_sdk 1.2.0 copy "onecxi_flutter_sdk: ^1.2.0" to clipboard
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 legacy flutter_background_service boot-restart behavior. Defaults to false; on Android the native OneCxiCallService handles call lifecycle, so boot restart is not required.
  • Full-screen-intent helpers. canUseFullScreenIntent() and ensureFullScreenIntentPermission() 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 enumerated activeNotifications and cancelled every notification except its own, and swept notification IDs 1000..1020. It now cancels only the SDK's own incoming-call notification IDs (1001 / 1002 / 1003, via the new SDK_INCOMING_CALL_NOTIFICATION_IDS constant) 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): NativeWebSocketClient only recognized an end event inside specific type branches, so a backend end message with a different type was ignored and the call never ended. The end signal (End / Ended / stop / close_connection / Disconnected) is now detected regardless of type, 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 isCallOngoing true). It now routes through the full call-end teardown (dismiss CallKit UI + reset state) via a new AudioHelper.onRemoteCallEnded callback.
  • Android — reliable call-end teardown on Android 14+ / OEM ROMs. The internal CALL_EVENT and CLOSE_CALL_SCREEN broadcasts 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 with initialize(verboseLogs: true) or setOneCxiVerboseLogs(true) (the setVerboseLogs method channel is now handled on Android). Errors and warnings still always log.

1.1.2+2 - 2026-05-23 #

Fixed #

  • Android compileDebugKotlin failure on 1.1.2+1: Removed duplicate KeyguardManager import in CallScreenActivity.kt (accidental duplicate introduced in 1.1.2+1).

Changed #

  • Android build: Kotlin 2.3.10 and Android Gradle Plugin 8.11.1 (was 1.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 90103 and correct WebSocket routing when FCM sends invalid callFrom/callTo. stopDartAudioOnly() prevents accidental call teardown on accept (no spurious /api/call-end 403).
  • Android remote hangup: Native onCallEnded / onCallDisconnected, WebSocket Ended, and FCM agent_disconnect / event=end now propagate to Flutter for UI and notification cleanup when the agent disposes the call.
  • Android ghost “OneCxi Call Active” notifications: Native OneCxiCallService is the sole ongoing-call foreground notification owner on Android; CallBackgroundService no longer starts duplicate flutter_background_service FGS. Stale notification taps close safely; cleanupStaleCallState runs on SDK init.
  • Android MissingForegroundServiceTypeException: SDK library manifest merges BackgroundService with foregroundServiceType="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): set autoStartOnBoot: false so 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: WebSocket wss://web-stream.cloudagent.ozonetel.com/, REST base https://streamingapi.cloudagent.ozonetel.com (override with initialize(serverName: …) if your API host differs).
  • Session correlation: push / FCM callId used as WebSocket ucid on iOS (Dart) and Android native service when present, so outbound media can attach to the server call.
  • Android native audio: AudioManager.MODE_IN_COMMUNICATION set during AudioTrack initialization (NativeAudioHelper).
  • Android native WebSocket: after connect, mirrors Dart handshake — sendReadyMessage, sendAudioFormatMessage, sendRequestIncomingAudio (timed), outbound sendAudioRequestMessage + startPeriodicAudioRequests.
  • HTTP call-end: uses REST origin from initialize() serverName when set, else SdkConfig.baseUrl.
  • Example app: AppConfig server / registration URLs aligned to cloudagent hosts.

Fixed #

  • UCID: webSocketInitialize no longer overwrites _ucid when already set (e.g. from push callId).

Integrator notes #

  • Confirm API keys and serverName for your environment; defaults target Ozonetel cloudagent production.
  • Remove or ignore duplicate sources under android/.../com/onecxi/flutter/sdk/ if present; the plugin uses com.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 information
  • isCallActive() method to check call status from native layer
  • forceEndCall() 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
  • showWhenLocked and turnScreenOn support 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 OneCxiCallService companion object
  • iOS: Call state persisted in UserDefaults for cross-session tracking
  • Enhanced getNativeCallStatus with 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 EOFException for 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:

  1. 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" />
  1. Update MainActivity (Android):
<activity
    android:name=".MainActivity"
    android:showWhenLocked="true"
    android:turnScreenOn="true"
    ...>
</activity>
  1. 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