# flutter_callkit_incoming 3.1.6

Flutter Callkit Incoming to show callkit screen in your Flutter app.




## Installing
```
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add flutter_callkit_incoming
```
Published: 2026-09-22T10:26:07.315728Z
Expected archive SHA-256: 2d47db2e8d32d333e0352d37b0a4e643f606a54f8a541db17af7c42f18c58318

Available in cache; verification: upstream_checksum
## Direct dependencies
- flutter: map[sdk:flutter]
- json_annotation: ^4.9.0

## Package README (untrusted upstream documentation)
# Flutter Callkit Incoming

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

[![pub package](https://img.shields.io/pub/v/flutter_callkit_incoming.svg)](https://pub.dev/packages/flutter_callkit_incoming)
[![pub points](https://img.shields.io/pub/points/flutter_callkit_incoming?label=pub%20points)](https://pub.dev/packages/flutter_callkit_incoming/score)
[![GitHub stars](https://img.shields.io/github/stars/hiennguyen92/flutter_callkit_incoming.svg?style=social)](https://github.com/hiennguyen92/flutter_callkit_incoming/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/hiennguyen92/flutter_callkit_incoming.svg?style=social)](https://github.com/hiennguyen92/flutter_callkit_incoming/network)
[![GitHub license](https://img.shields.io/github/license/hiennguyen92/flutter_callkit_incoming.svg)](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/LICENSE)
[![Build Status](https://github.com/hiennguyen92/flutter_callkit_incoming/actions/workflows/main.yml/badge.svg)](https://github.com/hiennguyen92/flutter_callkit_incoming/actions/workflows/main.yml)

## Sponsors

Our top sponsors are shown below!

<a href="https://getstream.io/video/sdk/flutter/tutorial/video-calling/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Video&utm_term=flutter_callkit" target="_blank">
  <img width="250px" src="https://stream-blog.s3.amazonaws.com/blog/wp-content/uploads/fc148f0fc75d02841d017bb36e14e388/Stream-logo-with-background-.png"/>
</a>
<br/>
<span>
  <a href="https://getstream.io/video/sdk/flutter/tutorial/video-calling/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Video&utm_term=flutter_callkit" target="_blank">Try the Flutter Video Tutorial 📹</a>
</span>
</br>
</br>
<a href="https://www.buymeacoffee.com/hiennguyen92" target="_blank">
  <img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174">
</a>

## 📌 Table of Contents
- [⭐ Features](#-features)
- [🚀 Installation](#-installation)
  - [1. Install Packages](#1-install-packages)
  - [2. Configure Project](#2-configure-project)
    - [Android Configuration](#android)
    - [iOS Configuration](#ios)
    - [Swift Package Manager (SPM) Support](#swift-package-manager-spm-support-flutter-324)
  - [3. Usage](#3-usage)
- [📋 Properties](#-properties)
- [📱 Pushkit Setup](#-pushkit---received-voip-and-wake-app-from-terminated-state-ios-only)
- [🎯 Demo](#-demo)

## ⭐ 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](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/PUSHKIT.md) 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:**
```bash
flutter pub add flutter_callkit_incoming
```

**Or add to pubspec.yaml:**
```yaml
dependencies:
  flutter_callkit_incoming: ^latest
```

### 2. Configure Project

#### Android

**AndroidManifest.xml:**
```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:**
```xml
<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:

```bash
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
```dart
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
```

#### Show Incoming Call
```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: <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`:

```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."
});
```

#### Request Full Intent Permission (Android 14+)

For Android 14+, please use `canUseFullScreenIntent` and `requestFullIntentPermission`:

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

// Request full intent permission
await FlutterCallkitIncoming.requestFullIntentPermission();
```

#### Show 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: <String, dynamic>{'userId': '1a2b3c4d'},
);
await FlutterCallkitIncoming.showMissCallNotification(params);
```

#### Hide Call Notification (Android)
```dart
CallKitParams params = CallKitParams(
  id: _currentUuid,
);
await FlutterCallkitIncoming.hideCallkitIncoming(params);
```

#### Start Outgoing Call
```dart
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
```dart
// 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

```dart
await FlutterCallkitIncoming.activeCalls();
```

**Output:**
```json
[{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}]
```

#### Set Call Connected

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

```dart
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

```dart
await FlutterCallkitIncoming.getDevicePushTokenVoIP();
```

**Output:**
```
d6a77ca80c5f09f87f353cdd328ec8d7d34e92eb108d046c91906f27f54949cd
```

> **Important:** Make sure using `SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)` inside AppDelegate.swift ([Example](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/example/ios/Runner/AppDelegate.swift))

```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("")
}
```

#### Listen Events
```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;
  }
});
```

#### Call from Native (iOS/Android)

**Swift (iOS):**
```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
```

**Kotlin (Android):**
```kotlin
FlutterCallkitIncomingPlugin.getInstance().showIncomingNotification(...)
```

**Alternative Swift approach:**
```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:**
```objc
#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:**
```swift
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendEventCustom(body: ["customKey": "customValue"])
```

**Kotlin:**
```kotlin
FlutterCallkitIncomingPlugin.getInstance().sendEventCustom(body: Map<String, Any>)
```

#### Call API when Accept/Decline/End/Timeout
#### Setup for Missed call notification(iOS)

**AppDelegate.swift:**
```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](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/example/ios/Runner/AppDelegate.swift)
**Create MMainApplication.kt in your source directory **

**MainApplication.kt:**
```kotlin
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](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/example/android/app/src/main/kotlin/com/example/flutter_callkit_incoming_example/MainActivity.kt
)

## 📋 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](https://pub.dev/packages/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` <br>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` <br> 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`<br>`system_ringtone_default` <br>using ringtone default of the phone |

## 📁 Source Code

Please checkout repo GitHub:
- [https://github.com/hiennguyen92/flutter_callkit_incoming](https://github.com/hiennguyen92/flutter_callkit_incoming)
- [Example](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/example/lib/main.dart)

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

Please check [PUSHKIT.md](https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/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

<table>
  <tr>
    <td><strong>iOS (Lockscreen)</strong></td>
    <td><strong>iOS (Full Screen)</strong></td>
    <td><strong>iOS (Alert)</strong></td>
  </tr>
  <tr>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image1.png" width="220" alt="iOS Lockscreen">
    </td>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image2.png" width="220" alt="iOS Full Screen">
    </td>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image3.png" width="220" alt="iOS Alert">
    </td>
  </tr>
  <tr>
    <td><strong>Android (Lockscreen) - Audio</strong></td>
    <td><strong>Android (Alert) - Audio</strong></td>
    <td><strong>Android (Lockscreen) - Video</strong></td>
  </tr>
  <tr>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image4.jpg" width="220" alt="Android Lockscreen Audio">
    </td>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image5.jpg" width="220" alt="Android Alert Audio">
    </td>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image6.jpg" width="220" alt="Android Lockscreen Video">
    </td>
  </tr>
  <tr>
    <td><strong>Android (Alert) - Video</strong></td>
    <td><strong>isCustomNotification: false</strong></td>
    <td></td>
  </tr>
  <tr>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image7.jpg" width="220" alt="Android Alert Video">
    </td>
    <td>
      <img src="https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/image8.jpg" width="220" alt="Custom Notification False">
    </td>
    <td></td>
  </tr>
</table> 
## Changelog
## 3.1.6

Hotfix release. Low-risk corrections only — no API changes.

**Behaviour changes to be aware of**
* Android: `${applicationId}.PERMISSION_CALL` is now `signature` instead of `normal`. Any app could previously request it and forge incoming/accept/decline broadcasts. Only affects setups where a separately-signed companion app sends these broadcasts.
* Android: the incoming and ongoing notifications now use the app's own icon as the small icon. Previously an internal drawable always won, so the app icon could never appear.
* Android: the ringtone now respects silent and vibrate ringer modes. It previously played in silent mode.
* iOS: **minimum deployment target raised to 15.0** (podspec was 10.0, `Package.swift` was 13.0). Xcode 26/27 refuse any target below 15.0 outright, so 3.1.5 could not be built with current Xcode at all. Apps still on an older Xcode that need iOS 13/14 should stay on 3.1.5.
  If your own `Podfile`/Xcode project is still below 15.0 you must raise it too, and you may need a `post_install` hook forcing `IPHONEOS_DEPLOYMENT_TARGET` for dependencies that declare very old targets — the example app's `Podfile` shows the pattern.

**Fixes**
* iOS: `ACTION_CALL_DECLINE` stopped being emitted, and incoming calls stopped timing out, after the first outgoing call in a process. The internal call-state slots were never cleared.
* iOS: `timedOutPerforming` resolved the call by the action's own identifier instead of `CXCallAction.callUUID`, so it never matched and `onTimeOut` never fired. It also fulfilled/failed a timed-out action, which `CXProvider` forbids.
* iOS: the ringtone condition used `||` where `&&` was meant, setting an empty `ringtoneSound` on the provider configuration.
* iOS: removed 2602 trailing NUL bytes from `SwiftFlutterCallkitIncomingPlugin.swift`, which made `grep`/`rg` treat the file as binary and skip it. Line endings normalised to LF.
* iOS: the podspec pinned `VALID_ARCHS` to `x86_64` for the simulator, breaking arm64 simulator builds on Apple Silicon. Now uses `EXCLUDED_ARCHS`.
* iOS: added `PrivacyInfo.xcprivacy` declaring the `UserDefaults` required-reason API (`CA92.1`). Verified to ship on both integration paths — inside `flutter_callkit_incoming.framework` under CocoaPods, and as a resource bundle under Swift Package Manager.
* iOS: podspec version now tracks the package version instead of being pinned at `0.0.1`.
* Android: an unknown method channel call returned without submitting a result, leaving the Dart `Future` pending forever. Replies are now routed through a guard so a throw after a successful reply can no longer raise `Reply already submitted`.
* Android: `registerPhoneAccount` could throw on the plugin-attach path and crash the host app at startup.
* Android: the incoming-call screen acquired a wake lock and never released it, keeping the screen on for the full ring duration even after the call was answered or declined.
* Android: `incomingChannelEnabled()` had an operator-precedence bug that reported channels as enabled on pre-Android-8 devices even when notifications were disabled.
* Android: the accept action's label fell back to the default when `textDecline` was empty rather than `textAccept`.
* Android: the incoming-call screen's dynamic receiver was registered as `RECEIVER_EXPORTED` for an app-private action.
* Android: `unregisterReceiver` is now guarded against `IllegalArgumentException`.
* Android: added `android:showWhenLocked` to the incoming-call activity; several OEMs honour only the manifest attribute.
* Android: dropped the unused `androidx.localbroadcastmanager` dependency.

## 3.1.5
* Fix Android: resolve build errors introduced in 3.1.4.
* Fix Android: always call `startForeground` to prevent `ForegroundServiceDidNotStartInTimeException`, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/857
* Fix Android: remove automatic launch of full screen intent settings that crashes `CallkitIncomingActivity` on Android 14+, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/856
* Fix Android: stop incoming ringtone from silencing itself, and silence it correctly on volume-key press, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/855
* Fix Android: native `OnDecline` callback not running when app is in terminated state, thank @salamay https://github.com/hiennguyen92/flutter_callkit_incoming/pull/854
* Fix Android: complete Telecom hold integration for self-managed calls, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/852
* Fix Android: only add `MICROPHONE`/`CAMERA` foreground service types when permission is granted, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/848
* Fix Android: restore foreground service on OS restart to prevent microphone loss in background, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/842
* Fix Android: `ActionCallToggleAudioSession` key name `isActivate` inconsistency, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/836
* Fix iOS: send `isActive` (not `isActivate`) in `ACTION_CALL_TOGGLE_AUDIO_SESSION` events, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/853
* Fix iOS: audio session ordering and end-call action handling for edge cases, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/850
* Fix iOS: don't re-answer an already-connected call in `connectedCall`, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/849
* Fix iOS: crash on `ACTION_CALL_CUSTOM` — convert event body instead of unsafe cast, thank @andrei-uni https://github.com/hiennguyen92/flutter_callkit_incoming/pull/847

## 3.1.4

* Fix Android: always call `startForeground` to prevent `ForegroundServiceDidNotStartInTimeException`, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/857
* Fix Android: remove automatic launch of full screen intent settings that crashes `CallkitIncomingActivity` on Android 14+, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/856
* Fix Android: stop incoming ringtone from silencing itself, and silence it correctly on volume-key press, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/855
* Fix Android: native `OnDecline` callback not running when app is in terminated state, thank @salamay https://github.com/hiennguyen92/flutter_callkit_incoming/pull/854
* Fix Android: complete Telecom hold integration for self-managed calls, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/852
* Fix Android: only add `MICROPHONE`/`CAMERA` foreground service types when permission is granted, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/848
* Fix Android: restore foreground service on OS restart to prevent microphone loss in background, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/842
* Fix Android: `ActionCallToggleAudioSession` key name `isActivate` inconsistency, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/836
* Fix iOS: send `isActive` (not `isActivate`) in `ACTION_CALL_TOGGLE_AUDIO_SESSION` events, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/853
* Fix iOS: audio session ordering and end-call action handling for edge cases, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/850
* Fix iOS: don't re-answer an already-connected call in `connectedCall`, thank @m-lhb https://github.com/hiennguyen92/flutter_callkit_incoming/pull/849
* Fix iOS: crash on `ACTION_CALL_CUSTOM` — convert event body instead of unsafe cast, thank @andrei-uni https://github.com/hiennguyen92/flutter_callkit_incoming/pull/847

## 3.1.3
* Fix Android: do not launch app when call is declined from self-managed Telecom connection, thank @iboogey https://github.com/hiennguyen92/flutter_callkit_incoming/pull/829

## 3.1.2
* Fix pack mapped data to expose call event, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/823
* Fix iOS: restore maximumCallGroups config, hold handler, holdCall event, thank @md-riaz https://github.com/hiennguyen92/flutter_callkit_incoming/pull/825

## 3.1.1
* Reorganize iOS native source directory to support Swift Package Manager (SPM) by placing all source files inside the package root (`ios/flutter_callkit_incoming/Classes/`).
* Resolve SPM mixed-language constraint by removing Objective-C wrappers and implementing a pure-Swift registrar class `@objc(FlutterCallkitIncomingPlugin)` to ensure seamless CocoaPods backward compatibility.
* Modernize example app's Objective-C imports in `AppDelegate.m` using Clang module import syntax `@import flutter_callkit_incoming;`.

## 3.1.0
* Add native **Swift Package Manager (SPM)** support for iOS with auto-linked `CryptoSwift` dependency.
* Add explicit Objective-C compatible overload `showCallkitIncoming(_:fromPushKit:)` in `SwiftFlutterCallkitIncomingPlugin` to fix compilation issues in native Objective-C runner.
* Conform `AppDelegate` in example project to `CallkitIncomingAppDelegate` by implementing the missing `providerDidReset()` method.
* Update environment constraints in `pubspec.yaml` to require Dart SDK `>=3.0.0` and Flutter `>=3.10.0`.
* Add optional `onError` completion handler to `showCallkitIncoming` for iOS, thank @nukeolay https://github.com/hiennguyen92/flutter_callkit_incoming/pull/803
* Implement self-managed Telecom ConnectionService on Android, thank @kennss https://github.com/hiennguyen92/flutter_callkit_incoming/pull/809
* Add Background Message Handler and Enhanced Android Foreground Service Support, thank @fedehsq https://github.com/hiennguyen92/flutter_callkit_incoming/pull/800
* Fix Android duplicated notification on call connected event, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/764
* Refactor and improve type safety, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/772
* Implement volume key handling to mute incoming call sound on key press, thank @jawad1257 https://github.com/hiennguyen92/flutter_callkit_incoming/pull/781
* Fix ongoing ringtone and vibrations on the action call connected, thank @skutimechanic https://github.com/hiennguyen92/flutter_callkit_incoming/pull/783
* Add custom color option for accept and decline buttons for Android, thank @baldarama https://github.com/hiennguyen92/flutter_callkit_incoming/pull/790
* Fix Android ringtone/vibration stopping on auto lock, thank @phildupuis https://github.com/hiennguyen92/flutter_callkit_incoming/pull/792
* Dynamically update CXProvider configuration for subsequent calls on iOS, thank @MS-Rex https://github.com/hiennguyen92/flutter_callkit_incoming/pull/805
* Fix Android showCallkitIncoming silently dropping calls when host process is kept alive, thank @sherzodkamoldinov https://github.com/hiennguyen92/flutter_callkit_incoming/pull/808
* Refactor notification and sound management: Updated incoming notification, thank @AbdurahmanAlmehdi https://github.com/hiennguyen92/flutter_callkit_incoming/pull/812
* Fix iOS outgoing call actionCallAccept emitting default/empty Data instead of original call params, thank @mechtech-mind https://github.com/hiennguyen92/flutter_callkit_incoming/pull/813
* Fix and handle null intent.action in TransparentActivity, thank @AlexBacich https://github.com/hiennguyen92/flutter_callkit_incoming/pull/814

## 3.0.0
* Using Plugin DSL for Android, thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/743
* Add Android native callback, thank @joshoconnor89 https://github.com/hiennguyen92/flutter_callkit_incoming/pull/736
* Improve plugin lifecycle, thank @lohzi97 https://github.com/hiennguyen92/flutter_callkit_incoming/pull/746
* Fixed some bugs.

## 2.5.8
* Fix OnGoing notification Android
* Add missed call notification for iOS(notification/callback action - need to setup more in AppDelegate.swift)
* Add `requestNotificationPermission` for iOS

## 2.5.7
* Fix build Android
* Fix stop sound notification when screen off Android

## 2.5.6
* Fix bug duplicate permission Android
* Replaces MediaPlayer with Ringtone Android
* Fix bug notification channel Android
* Stop sound notification when screen off Android

## 2.5.5
* Fix bug duplicate permission Android

## 2.5.4
* Fix bug custom permission Android
* Remove calling notification when task remove
* Fixed calling notification show
* Fixed some bugs.

## 2.5.3
* Update Android 14+ compatibility(force CallStyle/`FOREGROUND_SERVICE_PHONE_CALL` for https://developer.android.com/about/versions/14/behavior-changes-all#non-dismissable-notifications)
* Change structure Notification/Sound on Android
* Update get avatar from assets(Android), thanks @Ricky-yu https://github.com/hiennguyen92/flutter_callkit_incoming/pull/674
* Add `isAccepted` properties for iOS and only show facetime button if support video, thank @td2thinh https://github.com/hiennguyen92/flutter_callkit_incoming/pull/673
* Fixed some bugs.

## 2.5.3-alpha
* Update Android 14+ compatibility(force CallStyle/`FOREGROUND_SERVICE_PHONE_CALL` for https://developer.android.com/about/versions/14/behavior-changes-all#non-dismissable-notifications)
* Fixed some bugs.

## 2.5.2
* Add notification calling for Android `callingNotification`, thank @ebsangam https://github.com/hiennguyen92/flutter_callkit_incoming/pull/662
* Add `logoUrl` properties (inside android prop) 
* Fixed issue DMTF IOS, thank @minn-ee https://github.com/hiennguyen92/flutter_callkit_incoming/issues/577
* Fixed issue duplicate missing notification Android
* Fixed some bugs.

## 2.5.1
* Fix issue security Android, thanks @datpt11 https://github.com/hiennguyen92/flutter_callkit_incoming/issues/651

## 2.5.0
* update jvmToolchain(17) for Android

## 2.0.4+2
* add func `requestFullIntentPermission` (Android 14+) thank @Spyspyspy https://github.com/hiennguyen92/flutter_callkit_incoming/pull/584
* set Notification call style (Android) thank @AAkira https://github.com/hiennguyen92/flutter_callkit_incoming/pull/553
* Many other issues
    1. add prop `accepted` in activeCalls (iOS) thank @vasilich6107

## 2.0.4+1
* Removed `Telecom Framework` (Android)

## 2.0.4
* Removed `Telecom Framework` (Android)
* Fixed hide notification for action `CallBack` (Android)

## 2.0.3
* Fixed linked func `hideCallkitIncoming`

## 2.0.2+2
* Fixed linked func `hideCallkitIncoming`

## 2.0.2+1
* Fixed linked func `hideCallkitIncoming`

## 2.0.2
* Add func `hideCallkitIncoming` clear the incoming notification/ring (after accept/decline/timeout)
* Add props `isShowFullLockedScreen` on Android
* Fixed example/Fixed update android 14

## 2.0.1+2
* Add Action for onDecline
* Add Action for onEnd
* add android props `isShowCallID`

## 2.0.1+1
* Add Callback AVAudioSession for WebRTC setup
* Fix issue no audio for using WebRTC

## 2.0.1-dev.2
* Add Action for onAccept

## 2.0.1-dev.1
* Add AVAudioSession Appdelegate(iOS)

## 2.0.1-dev
* Add AVAudioSession Appdelegate(iOS)

## 2.0.1

* Fixed some bugs.
* `Android` using Telecom Framework
* Add `silenceEvents`
* Add `normalHandle` props https://github.com/hiennguyen92/flutter_callkit_incoming/pull/403
* Android add `textColor` props https://github.com/hiennguyen92/flutter_callkit_incoming/pull/398
* Android invisible avatar for default https://github.com/hiennguyen92/flutter_callkit_incoming/pull/393
* Add Method for call API when accept/decline/end/timeout

## 2.0.0+2

* Fixed some bugs.
* Support request permission for Android 13+ `requestNotificationPermission`

## 2.0.0+1

* Fixed some bugs.
* Add `landscape` for tablet
* Fix issue head-up for redmi / xiaomi devices

## 2.0.0

* Fixed some bugs.
* Adapt flutter_lints and use lowerCamelCase to Event enum
* Rename properties 
        `textMisssedCall` -> `subtitle`,
        `textCallback` -> `callbackText`,
        `isShowMissedCallNotification` -> `showNotification`,
* Move inside properties `missedCallNotification {showNotification, isShowCallback, subtitle, callbackText}`
* Add setCallConnected option iOS `await FlutterCallkitIncoming.setCallConnected(this._currentUuid)`
* Add hold option iOS
* Add mute call option iOS
* Many other issues
    1. Thank @ryojiro
    https://github.com/hiennguyen92/flutter_callkit_incoming/pull/263
    https://github.com/hiennguyen92/flutter_callkit_incoming/pull/264
    https://github.com/hiennguyen92/flutter_callkit_incoming/pull/262
    2. Many Thank @mouEsam
    https://github.com/hiennguyen92/flutter_callkit_incoming/pull/227
    3. ...


## 1.0.3+3

* Update README.md
* Fixed some bugs.

## 1.0.3+2

* REMOVED

## 1.0.3+1

* Dart class models instead using dynamic types and Maps (thank @icodelifee - https://github.com/hiennguyen92/flutter_callkit_incoming/pull/180)
* Allow to call from native Android (thank @fabiocody - https://github.com/hiennguyen92/flutter_callkit_incoming/pull/185)
* Add android notification channel name `incomingCallNotificationChannelName` `missedCallNotificationChannelName` (thank @AAkira - https://github.com/hiennguyen92/flutter_callkit_incoming/pull/177)
* Adding the feature to change template of notification to small `isCustomSmallExNotification` (thank @anocean2 - https://github.com/hiennguyen92/flutter_callkit_incoming/pull/196)
* Fixed ringtone sound not playing in Release mode on Android (thank @mschudt - https://github.com/hiennguyen92/flutter_callkit_incoming/pull/204)
* Fixed some bugs.

## 1.0.3

* REMOVED

## 1.0.2+2

* Fix notification Android 12
* Fix sound notification
* Support `backgroundUrl` using path assets
* Fixed some bugs.

## 1.0.2+1

* Issue no audio when Accept(iOS)
* Duplicate sound notification(Android)
* Support Flutter 3
* Fixed some bugs.

## 1.0.2

* Fixed issue open app(terminated/background state - Android).
* Completed Example  
* Fixed some bugs.

## 1.0.1+8

* Add props `isShowMissedCallNotification` using show Missed call notification(Android)
* Fixed issue decline(terminated/background state - there will be about 3 seconds to call the api before the app is closed.)
* Fixed some bugs.

## 1.0.1+7

* Fixed issue open app(terminated/background state).
* Fixed some bugs.

## 1.0.1+6

* Add props for text
* Fixed issue open app(terminated/background state).
* Fixed some bugs.

## 1.0.1+5

* Update custom miss call notification
* Fixed issue open app(terminated/background state).

## 1.0.1+4

* add `showMissCallNotification` only for Android, using show miss call notification 
* Fixed some bugs.

## 1.0.1+3

* add props `isShowCallback` using show Callback for miss call(Android)
* public props data call for Object-C/Swift
* Example using FCM(Android)
* Fixed some bugs.

## 1.0.1+2

* Fixed issue default ringtone(Android)
* Fixed issue vibration(Android)
* Fixed issue sound play type ringtone volumn system(Android)
* Fixed flow incomming screen(Android)
* Fixed some bugs.

## 1.0.1+1

* Switch using Service for Ringtone(Android)
* Fixed issue vibration(Android)
* Add `getDevicePushTokenVoIP()` feature
* Fixed some bugs.

## 1.0.1

* Pustkit and VoIP setup instructions (PUSHKIT.md)
* Callback from Recent History IOS
* Using System ringtone for default
* Fixed func `endAllCalls()` Android
* Bugs Android 12.
* Fixed some bugs.

## 1.0.0+8

* Share func call from native(iOS)

## 1.0.0+7

* Add custom `headers` using for avatar/background image (only for Android)

## 1.0.0+6

* Fixed func `activeCalls()` Get active calls

## 1.0.0+5

* Fixed endCall
* Bugs Targeting Android 12 (Android).
* Bugs `audio session` (iOS)
* Fixed some bugs.

## 1.0.0+4

* Update README.md.
* Add func `activeCalls()` Get active calls
* Remove notification when click action `Call back` (Android).
* Bugs `no activation of the audio session` (iOS)
* Fixed some bugs.

## 1.0.0+3

* Update README.md.
* Add props android `isShowLogo`.
* Fixed some bugs.

## 1.0.0+2

* Update README.md.
* Update documentation.

## 1.0.0+1

* Update README.md.
* Fixed some bugs.

## 1.0.0

* Initial release.







 
