diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 797acea5..00000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43164570..c5439d81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 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.
diff --git a/README.md b/README.md
index 58ee84b4..d58f0953 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
* Add pubspec.yaml:
```console
dependencies:
- flutter_callkit_incoming: ^1.0.0+2
+ flutter_callkit_incoming: any
```
2. Configure Project
* Android
@@ -116,6 +116,15 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
await FlutterCallkitIncoming.endAllCalls();
```
+ * Get active calls. iOS: return active calls from Callkit, Android: only return last call
+ ```dart
+ await FlutterCallkitIncoming.activeCalls();
+ ```
+ Output
+ ```json
+ [{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78"}]
+ ```
+
* Listen events
```dart
FlutterCallkitIncoming.onEvent.listen((event) {
@@ -221,6 +230,12 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
* https://github.com/hiennguyen92/flutter_callkit_incoming
+
+6. Todo
+ * Add `WakeLock` (background tasks) for Android
+ * Switch using `service` for Android
+
+
## :bulb: Demo
1. Demo Illustration:
diff --git a/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitIncomingBroadcastReceiver.kt b/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitIncomingBroadcastReceiver.kt
index 9e26d843..07ac66f2 100644
--- a/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitIncomingBroadcastReceiver.kt
+++ b/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitIncomingBroadcastReceiver.kt
@@ -151,9 +151,9 @@ class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {
}
ACTION_CALL_CALLBACK -> {
try {
+ callkitNotificationManager.clearMissCallNotification(data)
sendEventFlutter(ACTION_CALL_CALLBACK, data)
Utils.backToForeground(context)
- callkitNotificationManager.clearMissCallNotification(data)
val closeNotificationPanel = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
context.sendBroadcast(closeNotificationPanel)
} catch (error: Exception) {
diff --git a/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitNotificationManager.kt b/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitNotificationManager.kt
index c49f6bb2..4be7a66e 100644
--- a/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitNotificationManager.kt
+++ b/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/CallkitNotificationManager.kt
@@ -160,6 +160,7 @@ class CallkitNotificationManager(private val context: Context) {
}
fun showMissCallNotification(data: Bundle) {
+ notificationId = data.getString(EXTRA_CALLKIT_ID, "callkit_incoming").hashCode()
createNotificationChanel()
val missedCallSound: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val typeCall = data.getInt(EXTRA_CALLKIT_TYPE, -1)
@@ -222,6 +223,12 @@ class CallkitNotificationManager(private val context: Context) {
fun clearMissCallNotification(data: Bundle) {
notificationId = data.getString(EXTRA_CALLKIT_ID, "callkit_incoming").hashCode()
getNotificationManager().cancel(notificationId)
+ Handler(Looper.getMainLooper()).postDelayed({
+ try {
+ getNotificationManager().cancel(notificationId)
+ } catch (error: Exception) {
+ }
+ }, 1000)
}
private fun createNotificationChanel() {
@@ -286,7 +293,7 @@ class CallkitNotificationManager(private val context: Context) {
context,
id,
acceptIntent,
- PendingIntent.FLAG_UPDATE_CURRENT
+ PendingIntent.FLAG_CANCEL_CURRENT
)
}
diff --git a/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/FlutterCallkitIncomingPlugin.kt b/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/FlutterCallkitIncomingPlugin.kt
index 8aaa1390..debfa852 100644
--- a/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/FlutterCallkitIncomingPlugin.kt
+++ b/android/src/main/kotlin/com/hiennv/flutter_callkit_incoming/FlutterCallkitIncomingPlugin.kt
@@ -14,6 +14,8 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
+import org.json.JSONArray
+import org.json.JSONObject
/** FlutterCallkitIncomingPlugin */
class FlutterCallkitIncomingPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
@@ -38,6 +40,7 @@ class FlutterCallkitIncomingPlugin : FlutterPlugin, MethodCallHandler, ActivityA
private lateinit var callkitNotificationManager: CallkitNotificationManager
private lateinit var channel: MethodChannel
private lateinit var events: EventChannel
+ private var data: Data? = null
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
this.context = flutterPluginBinding.applicationContext
@@ -54,24 +57,24 @@ class FlutterCallkitIncomingPlugin : FlutterPlugin, MethodCallHandler, ActivityA
callkitNotificationManager = CallkitNotificationManager(this.context)
when (call.method) {
"showCallkitIncoming" -> {
- val data = Data(call.arguments())
- data.from = "notification"
- callkitNotificationManager.showIncomingNotification(data.toBundle())
+ data = Data(call.arguments())
+ data!!.from = "notification"
+ callkitNotificationManager.showIncomingNotification(data!!.toBundle())
//send BroadcastReceiver
context.sendBroadcast(
CallkitIncomingBroadcastReceiver.getIntentIncoming(
context,
- data.toBundle()
+ data!!.toBundle()
)
)
result.success("OK")
}
"startCall" -> {
- val data = Data(call.arguments())
+ data = Data(call.arguments())
context.sendBroadcast(
CallkitIncomingBroadcastReceiver.getIntentStart(
context,
- data.toBundle()
+ data!!.toBundle()
)
)
result.success("OK")
@@ -96,6 +99,15 @@ class FlutterCallkitIncomingPlugin : FlutterPlugin, MethodCallHandler, ActivityA
)
result.success("OK")
}
+ "activeCalls" -> {
+ val json = JSONArray()
+ if(data != null) {
+ val item = JSONObject()
+ item.put("id", data?.uuid)
+ json.put(item)
+ }
+ result.success(json.toString())
+ }
}
} catch (error: Exception) {
result.error("error", error.message, "")
diff --git a/example/lib/main.dart b/example/lib/main.dart
index eebcd057..a4cfc8b7 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -111,6 +111,15 @@ class _MyAppState extends State {
onPressed: () async {
this.startOutGoingCall();
},
+ ),
+ IconButton(
+ icon: Icon(
+ Icons.call_merge,
+ color: Colors.white,
+ ),
+ onPressed: () async {
+ this.activeCalls();
+ },
)
],
),
@@ -139,7 +148,7 @@ class _MyAppState extends State {
'appName': 'Callkit',
'avatar': 'https://i.pravatar.cc/100',
'handle': '0123456789',
- 'type': 1,
+ 'type': 0,
'duration': 30000,
'extra': {'userId': '1a2b3c4d'},
'android': {
@@ -188,4 +197,9 @@ class _MyAppState extends State {
}; //number/email
await FlutterCallkitIncoming.startCall(params);
}
+
+ Future activeCalls() async {
+ var calls = await FlutterCallkitIncoming.activeCalls();
+ print(calls);
+ }
}
diff --git a/example/pubspec.lock b/example/pubspec.lock
index ca26e4b7..88313eb2 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -75,7 +75,7 @@ packages:
path: ".."
relative: true
source: path
- version: "1.0.0+3"
+ version: "1.0.0+4"
flutter_test:
dependency: "direct dev"
description: flutter
diff --git a/ios/Classes/CallManager.swift b/ios/Classes/CallManager.swift
index 52154ca7..f60d804c 100644
--- a/ios/Classes/CallManager.swift
+++ b/ios/Classes/CallManager.swift
@@ -46,6 +46,17 @@ class CallManager: NSObject {
}
}
+ func activeCalls() -> [[String: String]] {
+ let calls = callController.callObserver.calls
+ var json = [[String: String]]()
+ for call in calls {
+ let item: [String: String] = ["id": call.uuid.uuidString]
+ json.append(item)
+ }
+ return json
+ }
+
+
func setHold(call: Call, onHold: Bool) {
let handleCall = CXSetHeldCallAction(call: call.uuid, onHold: onHold)
let callTransaction = CXTransaction()
diff --git a/ios/Classes/SwiftFlutterCallkitIncomingPlugin.swift b/ios/Classes/SwiftFlutterCallkitIncomingPlugin.swift
index f83d6b1a..b5494470 100644
--- a/ios/Classes/SwiftFlutterCallkitIncomingPlugin.swift
+++ b/ios/Classes/SwiftFlutterCallkitIncomingPlugin.swift
@@ -83,6 +83,9 @@ public class SwiftFlutterCallkitIncomingPlugin: NSObject, FlutterPlugin, CXProvi
}
result("OK")
break
+ case "activeCalls":
+ result(self.callManager?.activeCalls())
+ break;
case "endAllCalls":
self.callManager?.endCallAlls()
result("OK")
@@ -113,8 +116,10 @@ public class SwiftFlutterCallkitIncomingPlugin: NSObject, FlutterPlugin, CXProvi
let uuid = UUID(uuidString: data.uuid)
+ configurAudioSession()
self.sharedProvider?.reportNewIncomingCall(with: uuid!, update: callUpdate) { error in
if(error == nil) {
+ self.configurAudioSession()
let call = Call(uuid: uuid!)
call.handle = data.handle
self.callManager?.addCall(call)
@@ -349,7 +354,7 @@ public class SwiftFlutterCallkitIncomingPlugin: NSObject, FlutterPlugin, CXProvi
call.isOnHold = action.isOnHold
call.isMuted = action.isOnHold
self.callManager?.setHold(call: call, onHold: action.isOnHold)
- self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_HOLD, [ "uuid": action.callUUID, "isOnHold": action.isOnHold ])
+ self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_HOLD, [ "id": action.callUUID.uuidString, "isOnHold": action.isOnHold ])
action.fulfill()
}
@@ -359,7 +364,7 @@ public class SwiftFlutterCallkitIncomingPlugin: NSObject, FlutterPlugin, CXProvi
return
}
call.isMuted = action.isMuted
- self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_MUTE, [ "uuid": action.callUUID, "isMuted": action.isMuted ])
+ self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_MUTE, [ "id": action.callUUID.uuidString, "isMuted": action.isMuted ])
action.fulfill()
}
@@ -369,7 +374,7 @@ public class SwiftFlutterCallkitIncomingPlugin: NSObject, FlutterPlugin, CXProvi
return
}
//call.isMuted = action.isMuted
- self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_GROUP, [ "uuid": action.callUUID, "callUUIDToGroupWith" : action.callUUIDToGroupWith])
+ self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_GROUP, [ "id": action.callUUID.uuidString, "callUUIDToGroupWith" : action.callUUIDToGroupWith?.uuidString])
action.fulfill()
}
@@ -379,7 +384,7 @@ public class SwiftFlutterCallkitIncomingPlugin: NSObject, FlutterPlugin, CXProvi
return
}
//call.isMuted = action.isMuted
- self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_DMTF, [ "uuid": action.callUUID, "digits": action.digits, "type": action.type ])
+ self.sendEvent(SwiftFlutterCallkitIncomingPlugin.ACTION_CALL_TOGGLE_DMTF, [ "id": action.callUUID.uuidString, "digits": action.digits, "type": action.type ])
action.fulfill()
}
diff --git a/lib/flutter_callkit_incoming.dart b/lib/flutter_callkit_incoming.dart
index f8fe2b89..ee057aa8 100644
--- a/lib/flutter_callkit_incoming.dart
+++ b/lib/flutter_callkit_incoming.dart
@@ -58,6 +58,13 @@ class FlutterCallkitIncoming {
await _channel.invokeMethod("endAllCalls");
}
+ /// Get active calls.
+ /// On iOS: return active calls from Callkit.
+ /// On Android: only return last call
+ static Future activeCalls() async {
+ return await _channel.invokeMethod("activeCalls");
+ }
+
static CallEvent? _receiveCallEvent(dynamic data) {
var event = "";
dynamic body = {};
diff --git a/pubspec.yaml b/pubspec.yaml
index e7e38921..709b8ec4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_callkit_incoming
description: Flutter Callkit Incoming to show callkit screen in your Flutter app.
-version: 1.0.0+3
+version: 1.0.0+4
homepage: https://github.com/hiennguyen92/flutter_callkit_incoming
environment: