패키지, 저장소 및 앱 카테고리 검색

패키지 상세v3.1.6

flutter_callkit_incoming

Flutter Callkit Incoming을 사용하여 Flutter 앱에서 통화키트 화면을 표시합니다.

AndroidiOS
30일 다운로드
9.5만
좋아요
518
Pub 점수
160

패키지 설치

flutter pub add flutter_callkit_incoming

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Flutter CallKit Incoming은 Android 및 iOS에서 네이티브 통화 화면 통합을 가능하게 하는 Flutter 플러그인으로, 앱이 시스템 수준의 들어오는 통화 인터페이스를 표시할 수 있도록 합니다. 이는 플랫폼별로 특화된 CallKit(iOS) 및 PhoneAccount(Android) API를 활용하여 원활하고 시스템 네이티브 통화 경험을 제공합니다. 패키지는 Flutter 애플리케이션 내에서 통화 알림, 통화 수신 및 통화 종료 구현을 간소화하며, 기기 전체의 통화 행동과 일관성을 보장합니다. 실시간 통화 처리가 필요한 VoIP 또는 커뮤니케이션 앱에 적합합니다.

사용 사례

  • VoIP 통화 앱
  • 실시간 통신 플랫폼
  • 앱 내 통화 기능
  • 고객 지원 시스템
  • 원격의료 애플리케이션

주요 기능

  • 네이티브 통화 화면 표시
  • 시스템 레벨 호출 통합
  • 크로스 플랫폼 호환성
  • 최소 코드로 간편한 설정
  • 통화 응답/종료 작업 지원

적합한 대상

  • VoIP 앱을 개발하는 개발자
  • 네이티브 전화 UI가 필요한 앱
  • 실시간 통화를 통합하는 팀
  • 모바일 통신 솔루션
  • iOS 및 Android 앱 개발자

고려 사항

  • 플랫폼별 구성이 필요합니다
  • 모든 플랫폼에서 적절한 권한이 필요합니다
  • 백그라운드 실행 설정이 필요할 수 있습니다
  • 네이티브 UI의 사용자 정의 제한
  • 기기의 CallKit/PhoneAccount 사용 가능 여부에 따라 다름

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Flutter Callkit Incoming

A Flutter plugin to show incoming call in your Flutter app (Custom for Android/Callkit for iOS).

pub package pub points GitHub stars GitHub forks GitHub license Build Status

Sponsors

Our top sponsors are shown below!


Try the Flutter Video Tutorial 📹

Buy Me A Coffee

📌 Table of Contents

⭐ Features

  • Show an incoming call
  • Start an outgoing call
  • Custom UI Android/Callkit for iOS
  • Example using Pushkit/VoIP for iOS

[!WARNING]

iOS: ONLY WORKING ON REAL DEVICE

Please make sure setup/using PUSHKIT FOR VOIP

Note: Please do not use on simulator (Callkit framework is not fully supported on simulator for incoming VoIP calls).

🚀 Installation

1. Install Packages

For version >= v2.5.0, please make sure install and use Java SDK version >= 17 (Android)

Run this command:

flutter pub add flutter_callkit_incoming

Or add to pubspec.yaml:

dependencies:
  flutter_callkit_incoming: ^latest
2. Configure Project
Android

AndroidManifest.xml:

<manifest...>
    ...
    <!-- Using for load image from internet -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application ...>
        <activity ...
            android:name=".MainActivity"
            android:launchMode="singleInstance"><!-- add this -->
        ...
    </application>
</manifest>

Proguard Rules: The following rule needs to be added in the proguard-rules.pro to avoid obfuscated keys:

-keep class com.hiennv.flutter_callkit_incoming.** { *; }
iOS

Info.plist:

<key>UIBackgroundModes</key>
<array>
    <string>voip</string>
    <string>remote-notification</string>
    <string>processing</string> <!-- you can add this if needed -->
</array>
Swift Package Manager (SPM) Support (Flutter 3.24+)

This plugin natively supports Swift Package Manager (SPM). To configure your project to build using SPM instead of CocoaPods, run:

flutter config --enable-swift-package-manager

[!IMPORTANT] Swift Package Manager is highly recommended for modern Flutter projects as CocoaPods is in maintenance mode and will become read-only in December 2026.

3. Usage
Import
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
Show Incoming Call
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: <String, dynamic>{'userId': '1a2b3c4d'},
  headers: <String, dynamic>{'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);

Note: For Firebase Message: @pragma('vm:entry-point')
https://github.com/firebase/flutterfire/blob/master/docs/cloud-messaging/receive.md#apple-platforms-and-android

Request Notification Permission (Android 13+/iOS)

For Android 13+, please requestNotificationPermission or requestPermission of firebase_messaging before showCallkitIncoming:

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."
});
Request Full Intent Permission (Android 14+)

For Android 14+, please use canUseFullScreenIntent and requestFullIntentPermission:

// Check if can use full screen intent
await FlutterCallkitIncoming.canUseFullScreenIntent();

// Request full intent permission
await FlutterCallkitIncoming.requestFullIntentPermission();
Show Missed Call Notification
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: <String, dynamic>{'userId': '1a2b3c4d'},
);
await FlutterCallkitIncoming.showMissCallNotification(params);
Hide Call Notification (Android)
CallKitParams params = CallKitParams(
  id: _currentUuid,
);
await FlutterCallkitIncoming.hideCallkitIncoming(params);
Start Outgoing Call
this._currentUuid = _uuid.v4();
CallKitParams params = CallKitParams(
  id: this._currentUuid,
  nameCaller: 'Hien Nguyen',
  handle: '0123456789',
  type: 1,
  extra: <String, dynamic>{'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);
End Call
// End specific call
await FlutterCallkitIncoming.endCall(this._currentUuid);

// End all calls
await FlutterCallkitIncoming.endAllCalls();
Get Active Calls

iOS: returns active calls from Callkit (only id), Android: only returns last call

await FlutterCallkitIncoming.activeCalls();

Output:

[{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}]
Set Call Connected

Used to determine Incoming Call or Outgoing Call status in phone book(reset/start timer):

await FlutterCallkitIncoming.setCallConnected(this._currentUuid);

Note: After the call is ACCEPT or startCall, please call this function. Normally it should be called when WebRTC/P2P is established.

Get Device Push Token VoIP

iOS: returns deviceToken, Android: returns none

await FlutterCallkitIncoming.getDevicePushTokenVoIP();

Output:

d6a77ca80c5f09f87f353cdd328ec8d7d34e92eb108d046c91906f27f54949cd

Important: Make sure using SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken) inside AppDelegate.swift (Example)

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("")
}
Listen Events
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;
  }
});
Call from Native (iOS/Android)

Swift (iOS):

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

Kotlin (Android):

FlutterCallkitIncomingPlugin.getInstance().showIncomingNotification(...)

Alternative Swift approach:

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:

#if __has_include(<flutter_callkit_incoming/flutter_callkit_incoming-Swift.h>)
#import <flutter_callkit_incoming/flutter_callkit_incoming-Swift.h>
#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];

Send Custom Event from Native:

Swift:

SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendEventCustom(body: ["customKey": "customValue"])

Kotlin:

FlutterCallkitIncomingPlugin.getInstance().sendEventCustom(body: Map<String, Any>)
Call API when Accept/Decline/End/Timeout
Setup for Missed call notification(iOS)

AppDelegate.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
    }
    
    func didDeactivateAudioSession(_ audioSession: AVAudioSession) {
        // Use if using WebRTC
        // RTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession)
        // RTCAudioSession.sharedInstance().isAudioEnabled = false
    }
}

Please check full example: Example **Create MMainApplication.kt in your source directory **

MainApplication.kt:

import android.app.Application
import android.os.Bundle
import android.content.Context
import android.content.Intent
import android.util.Log
import com.hiennv.flutter_callkit_incoming.CallkitEventCallback
import com.hiennv.flutter_callkit_incoming.FlutterCallkitIncomingPlugin
import io.flutter.embedding.android.FlutterActivity
import org.json.JSONObject
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

private const val BASE_URL = "https://your-url/"
private const val TAG = "com.medeet.app.MainApplication"


class MainApplication : Application() {  // or FlutterApplication


  private var callkitEventCallback = object: CallkitEventCallback{
    override fun onCallEvent(event: CallkitEventCallback.CallEvent, callData: Bundle) {
      when (event) {
        CallkitEventCallback.CallEvent.ACCEPT -> {
          // Save accepted call id to SharedPreferences
          Log.d(TAG, "onAccept - Kotlin")

        }
        CallkitEventCallback.CallEvent.DECLINE -> {
          Log.d(TAG, "on Decline - Kotlin")
          val extra = callData.getSerializable("EXTRA_CALLKIT_EXTRA") as? HashMap<String, Any?>
          Log.d(TAG, "on Decline - $extra")
          sendDeclineCall(extra)
        }
        else -> {
          // Handle other cases or do nothing
        }
      }

    }
  }

  //Replace with your custom integration
  private fun sendDeclineCall(extra: HashMap<String, Any?>?) {
    // Read access token from SharedPreferences
    val prefs = applicationContext.getSharedPreferences(
      "FlutterSharedPreferences", Context.MODE_PRIVATE
    )
    val accessToken = prefs.getString("flutter.native_access_token", null)

    if (accessToken.isNullOrEmpty()) {
      Log.d(TAG, "declineCall - No access token found")
      return
    }
    val jsonBody = JSONObject((extra ?: emptyMap<String, Any?>()) as Map<*, *>)


    Log.d(TAG, "declineCall - body: $jsonBody")

    // Send request on background thread
    Thread {
      try {
        val url = URL("$BASE_URL/declineCall")
        val connection = url.openConnection() as HttpURLConnection
        connection.requestMethod = "POST"
        connection.setRequestProperty("Content-Type", "application/json")
        connection.setRequestProperty("Accept", "application/json")
        connection.setRequestProperty("Authorization", "Bearer $accessToken")
        connection.doOutput = true

        val writer = OutputStreamWriter(connection.outputStream)
        writer.write(jsonBody.toString())
        writer.flush()
        writer.close()
        val responseCode = connection.responseCode
        Log.d(TAG, "declineCall - Response status: $responseCode")
        connection.disconnect()
      } catch (e: Exception) {
        Log.e(TAG, "declineCall - Request error: ${e.message}")
      }
    }.start()
  }

  override fun onCreate() {
    super.onCreate()
    FlutterCallkitIncomingPlugin.registerEventCallback(callkitEventCallback)

  }
}

Add this to your app level build file

   defaultConfig {
     
      ......
        //Replace with your package name e.g "com.example.app.MainApplication"
        manifestPlaceholders["applicationName"] = "com.example.flutter_callkit_incoming_example.MainApplication"

    }

Point ${applicationName} at your new class in Android manifest

 <application
        ....
        android:name="${applicationName}"
         <activity
        

Please check full example: Example

📋 Properties

Main Properties
Property Description Default
id UUID identifier for each call. UUID should be unique for every call and when the call is ended, the same UUID for that call to be used. Suggest using uuid. ACCEPT ONLY UUID Required
nameCaller Caller's name None
appName App's name. Used for display inside Callkit (iOS). App Name, Deprecated for iOS > 14, default using App name
avatar Avatar's URL used for display for Android. /android/src/main/res/drawable-xxxhdpi/ic_default_avatar.png None
handle Phone number/Email/Any None
type 0 - Audio Call, 1 - Video Call 0
duration Incoming call/Outgoing call display time (second). If the time is over, the call will be missed 30000
textAccept Text Accept used in Android Accept
textDecline Text Decline used in Android Decline
extra Any data added to the event when received {}
headers Any data for custom header avatar/background image {}
missedCallNotification Android data needed to customize Missed Call Notification Below
callingNotification Android data needed to customize Calling Notification Below
android Android data needed to customize UI Below
ios iOS data needed Below
Missed Call Notification
Property Description Default
subtitle Text Missed Call used in Android/iOS (show in missed call notification) Missed Call
callbackText Text Call back used in Android/iOS (show in missed call notification action) Call back
showNotification Show missed call notification when timeout true
isShowCallback Show callback action from missed call notification true
Calling Notification
Property Description Default
subtitle Text used in Android (show in calling notification) Calling...
callbackText Text used in Android (show in calling notification action) Hang Up
showNotification Show calling notification when start call/accept call true
isShowCallback Show hang up action from calling notification true
Android
Property Description Default
isCustomNotification Using custom notifications false
isCustomSmallExNotification Using custom notification small on some devices clipped out in Android false
isShowLogo Show logo app inside full screen. /android/src/main/res/drawable-xxxhdpi/ic_logo.png false
logoUrl Logo app inside full screen. Example: http://... https://... or "assets/abc.png" None
ringtonePath File name of a ringtone ex: ringtone_default. Put file into /android/app/src/main/res/raw/ringtone_default.mp3 system_ringtone_default
using ringtone default of the phone
backgroundColor Incoming call screen background color #0955fa
backgroundUrl Using image background for Incoming call screen. Example: http://... https://... or "assets/abc.png" None
actionColor Color used in button/text on notification #4CAF50
textColor Color used for the text in full screen notification #ffffff
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
isShowFullLockedScreen Show full screen on Locked Screen (please make sure call requestFullIntentPermission for Android 14+) true
iOS
Property Description Default
iconName App's Icon. Used for display inside Callkit (iOS) CallKitLogo
using from Images.xcassets/CallKitLogo
handleType Type handle call generic, number, email, Recommended to use generic for more reasonable callkit display 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

📁 Source Code

Please checkout repo GitHub:

📱 Pushkit - Received VoIP and Wake App from Terminated State (iOS Only)

Please check PUSHKIT.md for setup Pushkit for iOS.

📋 Todo

  • [X] Run background / background execution support (implemented via self-managed Telecom service & didActivate background replay cache)
  • [X] Swift Package Manager (SPM) support
  • [ ] Simplify the setup process
  • [X] Custom notification for iOS (Missing notification)
  • [X] Keep notification when calling

🎯 Demo

Demo Illustration
Images
iOS (Lockscreen) iOS (Full Screen) iOS (Alert)
iOS Lockscreen iOS Full Screen iOS Alert
Android (Lockscreen) - Audio Android (Alert) - Audio Android (Lockscreen) - Video
Android Lockscreen Audio Android Alert Audio Android Lockscreen Video
Android (Alert) - Video isCustomNotification: false
Android Alert Video Custom Notification False

카테고리

의존성

의존성 목록 1 개

소스 저장소

이 패키지를 사용하는 프로젝트