### Testing with Curl Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/PUSHKIT Example cURL command to send a VoIP push notification to an iOS device. ```bash curl -v \ -d '{"aps":{"alert":"Hien Nguyen Call"},"id":"44d915e1-5ff4-4bed-bf13-c423048ec97a","nameCaller":"Hien Nguyen","handle":"0123456789","isVideo":true}' \ -H "apns-topic: com.hiennv.testing.voip" \ -H "apns-push-type: voip" \ --http2 \ --cert VOIP.pem:'' \ https://api.development.push.apple.com/3/device/ ``` -------------------------------- ### Testing with Curl Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/PUSHKIT.md Example cURL command to send a VoIP push notification to a device for testing purposes. ```bash curl -v \ -d '{"aps":{"alert":"Hien Nguyen Call"},"id":"44d915e1-5ff4-4bed-bf13-c423048ec97a","nameCaller":"Hien Nguyen","handle":"0123456789","isVideo":true}' \ -H "apns-topic: com.hiennv.testing.voip" \ -H "apns-push-type: voip" \ --http2 \ --cert VOIP.pem:'' \ https://api.development.push.apple.com/3/device/ ``` -------------------------------- ### Convert .p12 to .pem Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/PUSHKIT.md Command to convert a .p12 certificate file to a .pem file, which is necessary for Pushkit setup. ```bash openssl pkcs12 -in YOUR_CERTIFICATES.p12 -out VOIP.pem -nodes -clcerts ``` -------------------------------- ### Install Packages Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Command to add the flutter_callkit_incoming package to your Flutter project. ```bash flutter pub add flutter_callkit_incoming ``` -------------------------------- ### Show Incoming Call Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Example of how to show an incoming call using the plugin. ```swift Data * data = [[Data alloc]initWithId:@"44d915e1-5ff4-4bed-bf13-c423048ec97a" nameCaller:@"Hien Nguyen" handle:@"0123456789" type:1]; [data setNameCaller:@"Johnny"]; [data setExtra:@{ @"userId" : @"HelloXXXX", @"key2" : @"value2"}]; //... set more data [SwiftFlutterCallkitIncomingPlugin.sharedInstance showCallkitIncoming:data fromPushKit:YES]; ``` -------------------------------- ### Call API when accept/decline/end/timeout (iOS) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Example of handling call actions (accept, decline, end, timeout) and calling APIs. ```swift //Appdelegate ... @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate, CallkitIncomingAppDelegate { ... override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) //Setup VOIP let mainQueue = DispatchQueue.main let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue) voipRegistry.delegate = self voipRegistry.desiredPushTypes = [PKPushType.voIP] //Use if using WebRTC //RTCAudioSession.sharedInstance().useManualAudio = true //RTCAudioSession.sharedInstance().isAudioEnabled = false return super.application(application, didFinishLaunchingWithOptions: launchOptions) } // Func Call api for Accept func onAccept(_ call: Call, _ action: CXAnswerCallAction) { let json = ["action": "ACCEPT", "data": call.data.toJSON()] as [String: Any] print("LOG: onAccept") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") //Make sure call action.fulfill() when you are done(connected WebRTC - Start counting seconds) action.fulfill() case .failure(let error): print("Error: \(error.localizedDescription)") } } } // Func Call API for Decline func onDecline(_ call: Call, _ action: CXEndCallAction) { let json = ["action": "DECLINE", "data": call.data.toJSON()] as [String: Any] print("LOG: onDecline") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") //Make sure call action.fulfill() when you are done action.fulfill() case .failure(let error): print("Error: \(error.localizedDescription)") } } } // Func Call API for End func onEnd(_ call: Call, _ action: CXEndCallAction) { let json = ["action": "END", "data": call.data.toJSON()] as [String: Any] print("LOG: onEnd") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") //Make sure call action.fulfill() when you are done action.fulfill() case .failure(let error): print("Error: \(error.localizedDescription)") } } } func onTimeOut(_ call: Call) { let json = ["action": "TIMEOUT", "data": call.data.toJSON()] as [String: Any] print("LOG: onTimeOut") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") case .failure(let error): print("Error: \(error.localizedDescription)") } } } func didActivateAudioSession(_ audioSession: AVAudioSession) { //Use if using WebRTC //RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession) //RTCAudioSession.sharedInstance().isAudioEnabled = true } func didDeactivateAudioSession(_ audioSession: AVAudioSession) { //Use if using WebRTC //RTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession) //RTCAudioSession.sharedInstance().isAudioEnabled = false } ... ``` -------------------------------- ### Start Outgoing Call Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Initiates an outgoing call with specified parameters. ```dart this._currentUuid = _uuid.v4(); CallKitParams params = CallKitParams( id: this._currentUuid, nameCaller: 'Hien Nguyen', handle: '0123456789', type: 1, extra: {'userId': '1a2b3c4d'}, ios: IOSParams(handleType: 'generic'), callingNotification: const NotificationParams( showNotification: true, isShowCallback: true, subtitle: 'Calling...', callbackText: 'Hang Up', ), android: const AndroidParams( isCustomNotification: true, isShowCallID: true, ) ); await FlutterCallkitIncoming.startCall(params); ``` -------------------------------- ### Setup for Missed call notification (iOS) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md This code snippet shows the necessary modifications to the AppDelegate.swift file in an iOS project to handle missed call notifications, including foreground presentation and callback actions. ```swift @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate, CallkitIncomingAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) // Setup VOIP let mainQueue = DispatchQueue.main let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue) voipRegistry.delegate = self voipRegistry.desiredPushTypes = [PKPushType.voIP] // Use if using WebRTC // RTCAudioSession.sharedInstance().useManualAudio = true // RTCAudioSession.sharedInstance().isAudioEnabled = false //Add for Missed call notification if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate } return super.application(application, didFinishLaunchingWithOptions: launchOptions) } // Add for Missed call notification(show notification when foreground) override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { CallkitNotificationManager.shared.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler) } // Add for Missed call notification(action when click callback in missed notification) override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { if response.actionIdentifier == CallkitNotificationManager.CALLBACK_ACTION { let data = response.notification.request.content.userInfo as? [String: Any] SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendCallbackEvent(data) } completionHandler() } // Func Call API for Accept func onAccept(_ call: Call, _ action: CXAnswerCallAction) { let json = ["action": "ACCEPT", "data": call.data.toJSON()] as [String: Any] print("LOG: onAccept") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") // Make sure call action.fulfill() when you are done (connected WebRTC - Start counting seconds) action.fulfill() case .failure(let error): print("Error: \(error.localizedDescription)") } } } // Func Call API for Decline func onDecline(_ call: Call, _ action: CXEndCallAction) { let json = ["action": "DECLINE", "data": call.data.toJSON()] as [String: Any] print("LOG: onDecline") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") // Make sure call action.fulfill() when you are done action.fulfill() case .failure(let error): print("Error: \(error.localizedDescription)") } } } // Func Call API for End func onEnd(_ call: Call, _ action: CXEndCallAction) { let json = ["action": "END", "data": call.data.toJSON()] as [String: Any] print("LOG: onEnd") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") // Make sure call action.fulfill() when you are done action.fulfill() case .failure(let error): print("Error: \(error.localizedDescription)") } } } func onTimeOut(_ call: Call) { let json = ["action": "TIMEOUT", "data": call.data.toJSON()] as [String: Any] print("LOG: onTimeOut") self.performRequest(parameters: json) { result in switch result { case .success(let data): print("Received data: \(data)") case .failure(let error): print("Error: \(error.localizedDescription)") } } } func didActivateAudioSession(_ audioSession: AVAudioSession) { // Use if using WebRTC // RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession) // RTCAudioSession.sharedInstance().isAudioEnabled = true } } ``` -------------------------------- ### iOS Setup for Missed Call Notification Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Swift code snippet for handling audio session deactivation, potentially for WebRTC integration. ```swift func didDeactivateAudioSession(_ audioSession: AVAudioSession) { // Use if using WebRTC // RTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession) // RTCAudioSession.sharedInstance().isAudioEnabled = false } } ``` -------------------------------- ### Get Device Push Token VoIP Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md iOS: returns deviceToken, Android: returns none ```dart await FlutterCallkitIncoming.getDevicePushTokenVoIP(); ``` -------------------------------- ### Get device push token for VoIP (iOS) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Retrieves the device push token for VoIP. For Android, this returns an empty string. The output is a device token. Make sure to use `SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)` inside AppDelegate.swift. ```dart await FlutterCallkitIncoming.getDevicePushTokenVoIP(); ``` ```swift func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) { print(credentials.token) let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined() //Save deviceToken to your server SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken) } func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) { print("didInvalidatePushTokenFor") SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("") } ``` -------------------------------- ### Get Active Calls Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Retrieves a list of active calls. On iOS, it returns call IDs; on Android, it returns the last call. ```dart await FlutterCallkitIncoming.activeCalls(); ``` ```json [{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}] ``` -------------------------------- ### Project Repository Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Link to the project's GitHub repository. ```plaintext please checkout repo github https://github.com/hiennguyen92/flutter_callkit_incoming ``` -------------------------------- ### Android Manifest Configuration Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Add necessary permissions and proguard rules to your AndroidManifest.xml and proguard-rules.pro. ```xml ... ``` ```proguard -keep class com.hiennv.flutter_callkit_incoming.** { *; } ``` -------------------------------- ### Proguard Rules Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Proguard rules to add in proguard-rules.pro to avoid obfuscated keys. ```proguard -keep class com.hiennv.flutter_callkit_incoming.** { *; } ``` -------------------------------- ### Android Manifest Configuration Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Configuration for AndroidManifest.xml to enable internet access and set launchMode for the MainActivity. ```xml ... ... ``` -------------------------------- ### Call from Native (iOS) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Demonstrates how to show an incoming callkit call from native Swift code. It's important to call `completion()` at the end of `pushRegistry(......, completion: @escaping () -> Void)` or use `DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { completion() }` to prevent app crashes. ```swift var info = [String: Any?]() info["id"] = "44d915e1-5ff4-4bed-bf13-c423048ec97a" info["nameCaller"] = "Hien Nguyen" info["handle"] = "0123456789" info["type"] = 1 //... set more data SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(flutter_callkit_incoming.Data(args: info), fromPushKit: true) //please make sure call `completion()` at the end of the pushRegistry(......, completion: @escaping () -> Void) // or `DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { completion() }` // if you don't call completion() in pushRegistry(......, completion: @escaping () -> Void), there may be app crash by system when receiving voIP ``` ```swift let data = flutter_callkit_incoming.Data(id: "44d915e1-5ff4-4bed-bf13-c423048ec97a", nameCaller: "Hien Nguyen", handle: "0123456789", type: 0) data.nameCaller = "Johnny" data.extra = ["user": "abc@123", "platform": "ios"] //... set more data SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true) ``` -------------------------------- ### Objective-C Import Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Import statement for using the plugin in Objective-C. ```objectivec #if __has_include() #import #else #import "flutter_callkit_incoming-Swift.h" #endif ``` -------------------------------- ### Import Dart Package Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Import the flutter_callkit_incoming package in your Dart code. ```dart import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; ``` -------------------------------- ### iOS Info.plist Configuration Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Configuration for Info.plist in iOS to enable background modes for VoIP, remote notifications, and processing. ```xml UIBackgroundModes voip remote-notification processing ``` -------------------------------- ### Add to pubspec.yaml Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Alternatively, add the flutter_callkit_incoming package to your pubspec.yaml file. ```yaml dependencies: flutter_callkit_incoming: ^latest ``` -------------------------------- ### Show Incoming Call Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Demonstrates how to display an incoming call notification using CallKitParams. ```dart this._currentUuid = _uuid.v4(); CallKitParams callKitParams = CallKitParams( id: _currentUuid, nameCaller: 'Hien Nguyen', appName: 'Callkit', avatar: 'https://i.pravatar.cc/100', handle: '0123456789', type: 0, textAccept: 'Accept', textDecline: 'Decline', missedCallNotification: NotificationParams( showNotification: true, isShowCallback: true, subtitle: 'Missed call', callbackText: 'Call back', ), callingNotification: const NotificationParams( showNotification: true, isShowCallback: true, subtitle: 'Calling...', callbackText: 'Hang Up', ), duration: 30000, extra: {'userId': '1a2b3c4d'}, headers: {'apiKey': 'Abc@123!', 'platform': 'flutter'}, android: const AndroidParams( isCustomNotification: true, isShowLogo: false, logoUrl: 'https://i.pravatar.cc/100', ringtonePath: 'system_ringtone_default', backgroundColor: '#0955fa', backgroundUrl: 'https://i.pravatar.cc/500', actionColor: '#4CAF50', textColor: '#ffffff', incomingCallNotificationChannelName: "Incoming Call", missedCallNotificationChannelName: "Missed Call", isShowCallID: false ), ios: IOSParams( iconName: 'CallKitLogo', handleType: 'generic', supportsVideo: true, maximumCallGroups: 2, maximumCallsPerCallGroup: 1, audioSessionMode: 'default', audioSessionActive: true, audioSessionPreferredSampleRate: 44100.0, audioSessionPreferredIOBufferDuration: 0.005, supportsDTMF: true, supportsHolding: true, supportsGrouping: false, supportsUngrouping: false, ringtonePath: 'system_ringtone_default', ), ); await FlutterCallkitIncoming.showCallkitIncoming(callKitParams); ``` -------------------------------- ### Push Registry Update Credentials Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Handles updating push credentials for VoIP, saving the device token. ```swift func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) { print(credentials.token) let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined() // Save deviceToken to your server SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken) } ``` -------------------------------- ### Show Callkit Incoming (Alternative Swift) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Alternative method to initiate an incoming call notification on iOS using Swift with a Data object. ```swift let data = flutter_callkit_incoming.Data(id: "44d915e1-5ff4-4bed-bf13-c423048ec97a", nameCaller: "Hien Nguyen", handle: "0123456789", type: 0) data.nameCaller = "Johnny" data.extra = ["user": "abc@123", "platform": "ios"] // ... set more data SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true) ``` -------------------------------- ### Request Full Intent Permission (Android 14+) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Handles the request for full screen intent permission on Android 14+. ```dart // Check if can use full screen intent await FlutterCallkitIncoming.canUseFullScreenIntent(); // Request full intent permission await FlutterCallkitIncoming.requestFullIntentPermission(); ``` -------------------------------- ### iOS Callkit Properties Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Properties for configuring Callkit behavior on iOS, including icon, handle type, video support, and audio session settings. ```markdown | Prop | Description | Default | | ----------------------------------------- | ----------------------------------------------------------------------- | ----------- | | **`iconName`** | App's Icon. using for display inside Callkit(iOS) | `CallKitLogo`
using from `Images.xcassets/CallKitLogo` | | **`handleType`** | Type handle call `generic`, `number`, `email` | `generic` | | **`supportsVideo`** | | `true` | | **`maximumCallGroups`** | | `2` | | **`maximumCallsPerCallGroup`** | | `1` | | **`audioSessionMode`** | | _None_, `gameChat`, `measurement`, `moviePlayback`, `spokenAudio`, `videoChat`, `videoRecording`, `voiceChat`, `voicePrompt` | | **`audioSessionActive`** | | `true` | | **`audioSessionPreferredSampleRate`** | | `44100.0` | |**`audioSessionPreferredIOBufferDuration`**| | `0.005` | | **`supportsDTMF`** | | `true` | | **`supportsHolding`** | | `true` | | **`supportsGrouping`** | | `true` | | **`supportsUngrouping`** | | `true` | | **`ringtonePath`** | Add file to root project xcode `/ios/Runner/Ringtone.caf` and Copy Bundle Resources(Build Phases) |`Ringtone.caf`
`system_ringtone_default`
using ringtone default of the phone| ``` -------------------------------- ### Show Callkit Incoming (Kotlin Android) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Initiates an incoming call notification on Android using Kotlin. ```kotlin FlutterCallkitIncomingPlugin.getInstance().showIncomingNotification(...) ``` -------------------------------- ### Show Callkit Incoming (Objective-C) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Initiates an incoming call notification on iOS using Objective-C. ```objectivec #if __has_include() #import #else #import "flutter_callkit_incoming-Swift.h" #endif Data * data = [[Data alloc]initWithId:@"44d915e1-5ff4-4bed-bf13-c423048ec97a" nameCaller:@"Hien Nguyen" handle:@"0123456789" type:1]; [data setNameCaller:@"Johnny"]; [data setExtra:@{ @"userId" : @"HelloXXXX", @"key2" : @"value2"}]; // ... set more data [SwiftFlutterCallkitIncomingPlugin.sharedInstance showCallkitIncoming:data fromPushKit:YES]; ``` -------------------------------- ### Listen Events Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Listens for various call events from the CallKit/In-app Calling API. ```dart FlutterCallkitIncoming.onEvent.listen((CallEvent event) { switch (event!.event) { case Event.actionCallIncoming: // TODO: received an incoming call break; case Event.actionCallStart: // TODO: started an outgoing call // TODO: show screen calling in Flutter break; case Event.actionCallAccept: // TODO: accepted an incoming call // TODO: show screen calling in Flutter break; case Event.actionCallDecline: // TODO: declined an incoming call break; case Event.actionCallEnded: // TODO: ended an incoming/outgoing call break; case Event.actionCallTimeout: // TODO: missed an incoming call break; case Event.actionCallCallback: // TODO: click action `Call back` from missed call notification break; case Event.actionCallToggleHold: // TODO: only iOS break; case Event.actionCallToggleMute: // TODO: only iOS break; case Event.actionCallToggleDmtf: // TODO: only iOS break; case Event.actionCallToggleGroup: // TODO: only iOS break; case Event.actionCallToggleAudioSession: // TODO: only iOS break; case Event.actionDidUpdateDevicePushTokenVoip: // TODO: only iOS break; case Event.actionCallCustom: // TODO: for custom action break; } }); ``` -------------------------------- ### Show Callkit Incoming (Swift iOS) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Initiates an incoming call notification on iOS using Swift. ```swift var info = [String: Any?]() info["id"] = "44d915e1-5ff4-4bed-bf13-c423048ec97a" info["nameCaller"] = "Hien Nguyen" info["handle"] = "0123456789" info["type"] = 1 // ... set more data SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(flutter_callkit_incoming.Data(args: info), fromPushKit: true) // Please make sure call `completion()` at the end of the pushRegistry(......, completion: @escaping () -> Void) // or `DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { completion() }` // if you don't call completion() in pushRegistry(......, completion: @escaping () -> Void), there may be app crash by system when receiving VoIP ``` -------------------------------- ### Android MainActivity Kotlin Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Kotlin code snippet for MainActivity in an Android application, registering and unregistering Callkit event callbacks. ```kotlin class MainActivity: FlutterActivity(){ private var callkitEventCallback = object: CallkitEventCallback{ override fun onCallEvent(event: CallkitEventCallback.CallEvent, callData: Bundle) { when (event) { CallkitEventCallback.CallEvent.ACCEPT -> { // Do something with answer } CallkitEventCallback.CallEvent.DECLINE -> { // Do something with decline } } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FlutterCallkitIncomingPlugin.registerEventCallback(callkitEventCallback) } override fun onDestroy() { FlutterCallkitIncomingPlugin.unregisterEventCallback(callkitEventCallback) super.onDestroy() } } ``` -------------------------------- ### Send Custom Event (Kotlin) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Sends a custom event from native Kotlin code. ```kotlin FlutterCallkitIncomingPlugin.getInstance().sendEventCustom(body: Map) ``` -------------------------------- ### Send Custom Event (Swift) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Sends a custom event from native Swift code. ```swift SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendEventCustom(body: ["customKey": "customValue"]) ``` -------------------------------- ### Request Notification Permission (Android 13+) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Request notification permission for Android 13+ before showing an incoming call. ```dart await FlutterCallkitIncoming.requestNotificationPermission({ "rationaleMessagePermission": "Notification permission is required, to show notification.", "postNotificationMessageRequired": "Notification permission is required, Please allow notification permission from setting." }); ``` -------------------------------- ### Push Registry Invalidate Token Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Handles invalidating the push token for VoIP. ```swift func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) { print("didInvalidatePushTokenFor") SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("") } ``` -------------------------------- ### Request Notification Permission (Android 13+/iOS) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Requests notification permission for Android 13+ and iOS, which is required before showing call notifications. ```dart await FlutterCallkitIncoming.requestNotificationPermission({ "title": "Notification permission", "rationaleMessagePermission": "Notification permission is required, to show notification.", "postNotificationMessageRequired": "Notification permission is required, Please allow notification permission from setting." }); ``` -------------------------------- ### End Call Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Provides methods to end a specific call or all active calls. ```dart // End specific call await FlutterCallkitIncoming.endCall(this._currentUuid); // End all calls await FlutterCallkitIncoming.endAllCalls(); ``` -------------------------------- ### Android Incoming Call Notification Channel Configuration Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME Configuration options for notification channels related to incoming and missed calls on Android. ```markdown | **`incomingCallNotificationChannelName`** | Notification channel name of incoming call. | `Incoming call` | | **`missedCallNotificationChannelName`** | Notification channel name of missed call. | `Missed call` | | **`isShowCallID`** | Show call id app inside full screen/notification. | false | ``` -------------------------------- ### Show Missed Call Notification Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Configures and displays a missed call notification. ```dart this._currentUuid = _uuid.v4(); CallKitParams params = CallKitParams( id: _currentUuid, nameCaller: 'Hien Nguyen', handle: '0123456789', type: 1, missedCallNotification: const NotificationParams( showNotification: true, isShowCallback: true, subtitle: 'Missed call', callbackText: 'Call back', ), android: const AndroidParams( isCustomNotification: true, isShowCallID: true, ), extra: {'userId': '1a2b3c4d'}, ); await FlutterCallkitIncoming.showMissCallNotification(params); ``` -------------------------------- ### Ended All Calls Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME End all active calls. ```dart await FlutterCallkitIncoming.endAllCalls(); ``` -------------------------------- ### Set Call Connected Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Marks a call as connected, used for tracking call status and timers. ```dart await FlutterCallkitIncoming.setCallConnected(this._currentUuid); ``` -------------------------------- ### Ended an Incoming/Outgoing Call Source: https://github.com/hiennguyen92/flutter_callkit_incoming/wiki/HOME End a specific incoming or outgoing call using its UUID. ```dart await FlutterCallkitIncoming.endCall(this._currentUuid); ``` -------------------------------- ### Hide Call Notification (Android) Source: https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/README.md Hides the active call notification on Android. ```dart CallKitParams params = CallKitParams( id: _currentUuid, ); await FlutterCallkitIncoming.hideCallkitIncoming(params); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.