Last updated:
0 purchases
billtech incoming call
Flutter Callkit Incoming #
A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Callkit for iOS).
⭐ Features #
Show an incoming call
Start an outgoing call
Custom UI Android/Callkit for iOS
Example using Pushkit/VoIP for iOS
iOS: ONLY WORKING ON REAL DEVICE, not on simulator(Callkit framework not working on simulator) #
🚀 Installation #
Install Packages
Run this command:
flutter pub add billtech_incoming_call
copied to clipboard
Add pubspec.yaml:
dependencies:
billtech_incoming_call: any
copied to clipboard
Configure Project
Android
AndroidManifest.xml
<manifest...>
...
<!--
Using for load image from internet
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
copied to clipboard
iOS
Info.plist
<key>UIBackgroundModes</key>
<array>
<string>processing</string>
<string>remote-notification</string>
<string>voip</string>
</array>
copied to clipboard
Usage
Import
import 'package:billtech_incoming_call/billtech_incoming_call.dart';
copied to clipboard
Received an incoming call
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': _currentUuid,
'nameCaller': 'Hien Nguyen',
'appName': 'Callkit',
'avatar': 'https://i.pravatar.cc/100',
'handle': '0123456789',
'type': 0,
'textAccept': 'Accept',
'textDecline': 'Decline',
'textMissedCall': 'Missed call',
'textCallback': 'Call back',
'duration': 30000,
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'headers': <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
'android': <String, dynamic>{
'isCustomNotification': true,
'isShowLogo': false,
'isShowCallback': false,
'isShowMissedCallNotification': true,
'ringtonePath': 'system_ringtone_default',
'backgroundColor': '#0955fa',
'backgroundUrl': 'https://i.pravatar.cc/500',
'actionColor': '#4CAF50'
},
'ios': <String, dynamic>{
'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 BilltechIncomingCall.showCallkitIncoming(params);
copied to clipboard
Show miss call notification
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': this._currentUuid,
'nameCaller': 'Hien Nguyen',
'handle': '0123456789',
'type': 1,
'textMissedCall': 'Missed call',
'textCallback': 'Call back',
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
};
await BilltechIncomingCall.showMissCallNotification(params);
copied to clipboard
Started an outgoing call
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': this._currentUuid,
'nameCaller': 'Hien Nguyen',
'handle': '0123456789',
'type': 1,
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'ios': <String, dynamic>{'handleType': 'generic'}
};
await BilltechIncomingCall.startCall(params);
copied to clipboard
Ended an incoming/outgoing call
var params = <String, dynamic>{'id': this._currentUuid};
await BilltechIncomingCall.endCall(params);
copied to clipboard
Ended all calls
await BilltechIncomingCall.endAllCalls();
copied to clipboard
Get active calls. iOS: return active calls from Callkit, Android: only return last call
await BilltechIncomingCall.activeCalls();
copied to clipboard
Output
[{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}]
copied to clipboard
Get device push token VoIP. iOS: return deviceToken, Android: Empty
await BilltechIncomingCall.getDevicePushTokenVoIP();
copied to clipboard
Output
<device token>
//Example
d6a77ca80c5f09f87f353cdd328ec8d7d34e92eb108d046c91906f27f54949cd
copied to clipboard
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("")
}
copied to clipboard
Listen events
BilltechIncomingCall.onEvent.listen((event) {
switch (event!.name) {
case CallEvent.ACTION_CALL_INCOMING:
// TODO: received an incoming call
break;
case CallEvent.ACTION_CALL_START:
// TODO: started an outgoing call
// TODO: show screen calling in Flutter
break;
case CallEvent.ACTION_CALL_ACCEPT:
// TODO: accepted an incoming call
// TODO: show screen calling in Flutter
break;
case CallEvent.ACTION_CALL_DECLINE:
// TODO: declined an incoming call
break;
case CallEvent.ACTION_CALL_ENDED:
// TODO: ended an incoming/outgoing call
break;
case CallEvent.ACTION_CALL_TIMEOUT:
// TODO: missed an incoming call
break;
case CallEvent.ACTION_CALL_CALLBACK:
// TODO: only Android - click action `Call back` from missed call notification
break;
case CallEvent.ACTION_CALL_TOGGLE_HOLD:
// TODO: only iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_MUTE:
// TODO: only iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_DMTF:
// TODO: only iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_GROUP:
// TODO: only iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_AUDIO_SESSION:
// TODO: only iOS
break;
case CallEvent.ACTION_DID_UPDATE_DEVICE_PUSH_TOKEN_VOIP:
// TODO: only iOS
break;
}
});
copied to clipboard
Call from Native (iOS PushKit)
//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)
copied to clipboard
//OR
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)
copied to clipboard
//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];
copied to clipboard
//send custom event from native
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendEventCustom("customEvent", body: ["customKey": "customValue"])
copied to clipboard
Properties
Prop
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
Required
nameCaller
Caller's name.
None
appName
App's name. using 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
textMissedCall
Text Missed Call used in Android (show in miss call notification)
Missed Call
textCallback
Text Call back used in Android (show in miss call notification)
Call back
extra
Any data added to the event when received.
{}
headers
Any data for custom header avatar/background image.
{}
android
Android data needed to customize UI.
Below
ios
iOS data needed.
Below
Android
Prop
Description
Default
isCustomNotification
Using custom notifications.
false
isShowLogo
Show logo app inside full screen. /android/src/main/res/drawable-xxxhdpi/ic_logo.png
false
isShowMissedCallNotification
Show missed call notification when timeout
true
isShowCallback
Show callback action from miss call notification.
true
ringtonePath
File name ringtone. put file into /android/app/src/main/res/raw/ringtone_default.pm3
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
iOS
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.cafsystem_ringtone_default using ringtone default of the phone
Source code
please checkout repo github
https://github.com/hiennguyen92/flutter_callkit_incoming
copied to clipboard
https://github.com/billtech775/billtech_incoming_call
Example
Pushkit - Received VoIP and Wake app from Terminated State (only for IOS)
Please check PUSHKIT.md setup Pushkit for IOS
Todo
💡 Demo #
Demo Illustration:
Image
iOS(Lockscreen)
iOS(full screen)
iOS(Alert)
Android(Lockscreen) - Audio
Android(Alert) - Audio
Android(Lockscreen) - Video
Android(Alert) - Video
isCustomNotification: false
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.