From 5870e802552a6169e89578266c4a8aa2d8c09613 Mon Sep 17 00:00:00 2001 From: Aamir Muhammad Date: Mon, 3 Jul 2023 15:25:58 +0300 Subject: [PATCH] End Call Android --- .../com/mohem_flutter_app/CallDecline.kt | 318 ++++++++++++++++++ lib/classes/chat_call_kit.dart | 33 +- lib/ui/login/login_screen.dart | 32 +- pubspec.yaml | 2 + 4 files changed, 367 insertions(+), 18 deletions(-) create mode 100644 android/app/src/main/kotlin/com/mohem_flutter_app/CallDecline.kt diff --git a/android/app/src/main/kotlin/com/mohem_flutter_app/CallDecline.kt b/android/app/src/main/kotlin/com/mohem_flutter_app/CallDecline.kt new file mode 100644 index 0000000..73df479 --- /dev/null +++ b/android/app/src/main/kotlin/com/mohem_flutter_app/CallDecline.kt @@ -0,0 +1,318 @@ +//package com.mohem_flutter_app +//import kotlinx.coroutines.Dispatchers +//import kotlinx.coroutines.GlobalScope +//import kotlinx.coroutines.launch +//import okhttp3.* +//import okhttp3.MediaType.Companion.toMediaType +//import okhttp3.RequestBody.Companion.toRequestBody +//import java.io.IOException +// +//class NativeIncomingCallDecline { +// fun declineCall(currentUserID: String, targetUserID: String, token: String) { +// println("--------------- Inside Decline Call ----------------") +// val url = "https://apiderichat.hmg.com/api/user/calldecline" +// val payload = """ +// { +// "currentUserId": "$targetUserID", +// "targetUserId": "$currentUserID", +// "secretKey": "derichatmobileuser", +// "targetUserToken": "$token" +// } +// """.trimIndent() +// +// val jsonMediaType = "application/json".toMediaType() +// +// GlobalScope.launch(Dispatchers.IO) { +// val client = OkHttpClient() +// val requestBody = payload.toRequestBody(jsonMediaType) +// val request = Request.Builder() +// .url(url) +// .post(requestBody) +// .build() +// +// client.newCall(request).enqueue(object : Callback { +// override fun onResponse(call: Call, response: Response) { +// if (response.isSuccessful) { +// val responseData = response.body?.string() +// println("API Successful. Response data: $responseData") +// } else { +// val errorMessage = response.body?.string() +// println("API Failed. Error message: $errorMessage") +// } +// } +// +// override fun onFailure(call: Call, e: IOException) { +// println("API Request Failed. Exception: ${e.message}") +// } +// }) +// } +// } +//} +// + + + +//This code is included into CallkitIncomingBroadcastReceiver.kt file under Flutter_callKit_incoming Package +//Below is the Whole Code + +// Implemented Libraries into Kotlin +// implementation 'com.squareup.okhttp3:okhttp:4.9.1' +// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0' + +//package com.hiennv.flutter_callkit_incoming +//import android.annotation.SuppressLint +//import android.content.BroadcastReceiver +//import android.content.Context +//import android.content.Intent +//import android.os.Build +//import android.os.Bundle +//import android.util.Log +////http +//import okhttp3.MediaType.Companion.toMediaType +//import okhttp3.OkHttpClient +//import okhttp3.Request +//import okhttp3.RequestBody.Companion.toRequestBody +// +//// Async +//import kotlinx.coroutines.Dispatchers +//import kotlinx.coroutines.GlobalScope +//import kotlinx.coroutines.launch +// +//class CallkitIncomingBroadcastReceiver : BroadcastReceiver() { +// +// companion object { +// private const val TAG = "CallkitIncomingReceiver" +// +// fun getIntent(context: Context, action: String, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// this.action = "${context.packageName}.${action}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentIncoming(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_INCOMING}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentStart(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_START}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentAccept(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_ACCEPT}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentDecline(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_DECLINE}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentEnded(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_ENDED}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentTimeout(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_TIMEOUT}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// +// fun getIntentCallback(context: Context, data: Bundle?) = +// Intent(context, CallkitIncomingBroadcastReceiver::class.java).apply { +// action = "${context.packageName}.${CallkitConstants.ACTION_CALL_CALLBACK}" +// putExtra(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA, data) +// } +// } +// +// +// @SuppressLint("MissingPermission") +// override fun onReceive(context: Context, intent: Intent) { +// val callkitNotificationManager = CallkitNotificationManager(context) +// val action = intent.action ?: return +// val data = intent.extras?.getBundle(CallkitConstants.EXTRA_CALLKIT_INCOMING_DATA) ?: return +// +// when (action) { +// "${context.packageName}.${CallkitConstants.ACTION_CALL_INCOMING}" -> { +// try { +// callkitNotificationManager.showIncomingNotification(data) +// sendEventFlutter(CallkitConstants.ACTION_CALL_INCOMING, data) +// addCall(context, Data.fromBundle(data)) +// if (callkitNotificationManager.incomingChannelEnabled()) { +// val soundPlayerServiceIntent = +// Intent(context, CallkitSoundPlayerService::class.java) +// soundPlayerServiceIntent.putExtras(data) +// context.startService(soundPlayerServiceIntent) +// } +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// +// "${context.packageName}.${CallkitConstants.ACTION_CALL_START}" -> { +// try { +// sendEventFlutter(CallkitConstants.ACTION_CALL_START, data) +// addCall(context, Data.fromBundle(data), true) +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// +// "${context.packageName}.${CallkitConstants.ACTION_CALL_ACCEPT}" -> { +// try { +// sendEventFlutter(CallkitConstants.ACTION_CALL_ACCEPT, data) +// context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) +// callkitNotificationManager.clearIncomingNotification(data, true) +// addCall(context, Data.fromBundle(data), true) +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// +// "${context.packageName}.${CallkitConstants.ACTION_CALL_DECLINE}" -> { +// try { +// sendEventFlutter(CallkitConstants.ACTION_CALL_DECLINE, data) +// context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) +// callkitNotificationManager.clearIncomingNotification(data, false) +// removeCall(context, Data.fromBundle(data)) +// println("----------- Code By Aamir on 2222-----------------------"); +// var callData = data.getSerializable(CallkitConstants.EXTRA_CALLKIT_EXTRA) as HashMap +// val token = (callData["loginDetails"] as HashMap<*, *>)["token"] as? String +// val targetUserId = (callData["callerDetails"] as HashMap<*, *>)["targetUserId"] as? Int +// val currentUserId = (callData["callerDetails"] as HashMap<*, *>)["currentUserId"] as? Int +// delineCall(currentUserID = currentUserId, targetUserID = targetUserId, token = token) +// println("----------- Code By Aamir On BroadCast -----------------------"); +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// +// "${context.packageName}.${CallkitConstants.ACTION_CALL_ENDED}" -> { +// try { +// sendEventFlutter(CallkitConstants.ACTION_CALL_ENDED, data) +// context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) +// callkitNotificationManager.clearIncomingNotification(data, false) +// removeCall(context, Data.fromBundle(data)) +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// +// "${context.packageName}.${CallkitConstants.ACTION_CALL_TIMEOUT}" -> { +// try { +// sendEventFlutter(CallkitConstants.ACTION_CALL_TIMEOUT, data) +// context.stopService(Intent(context, CallkitSoundPlayerService::class.java)) +// if (data.getBoolean(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_SHOW, true)) { +// callkitNotificationManager.showMissCallNotification(data) +// } +// removeCall(context, Data.fromBundle(data)) +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// +// "${context.packageName}.${CallkitConstants.ACTION_CALL_CALLBACK}" -> { +// try { +// callkitNotificationManager.clearMissCallNotification(data) +// sendEventFlutter(CallkitConstants.ACTION_CALL_CALLBACK, data) +// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { +// val closeNotificationPanel = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) +// context.sendBroadcast(closeNotificationPanel) +// } +// } catch (error: Exception) { +// Log.e(TAG, null, error) +// } +// } +// } +// } +// +// +// private fun delineCall(currentUserID: Int?, targetUserID: Int?, token: String?) { +// println("--------------- Inside Decline Call ----------------"); +// val url = "https://apiderichat.hmg.com/api/user/calldecline" +// val payload = """ +// { +// "currentUserId": $targetUserID, +// "targetUserId": $currentUserID, +// "secretKey": "derichatmobileuser", +// "targetUserToken": "$token" +// } +// """.trimIndent() +// +// +// val jsonMediaType = "application/json".toMediaType() +// +// GlobalScope.launch(Dispatchers.IO) { +// val client = OkHttpClient() +// val requestBody = payload.toRequestBody(jsonMediaType) +// val request = Request.Builder() +// .url(url) +// .post(requestBody) +// .build() +// +// client.newCall(request).execute().use { response -> +// if (response.isSuccessful) { +// val responseData = response.body?.string() +// println("API Successful. Response data: $responseData") +// } else { +// val errorMessage = response.body?.string() +// println("API Failed. Error message: $errorMessage") +// } +// } +// } +// +// +// } +// +// +// private fun sendEventFlutter(event: String, data: Bundle) { +// val android = mapOf( +// "isCustomNotification" to data.getBoolean(CallkitConstants.EXTRA_CALLKIT_IS_CUSTOM_NOTIFICATION, false), +// "isCustomSmallExNotification" to data.getBoolean( +// CallkitConstants.EXTRA_CALLKIT_IS_CUSTOM_SMALL_EX_NOTIFICATION, +// false +// ), +// "ringtonePath" to data.getString(CallkitConstants.EXTRA_CALLKIT_RINGTONE_PATH, ""), +// "backgroundColor" to data.getString(CallkitConstants.EXTRA_CALLKIT_BACKGROUND_COLOR, ""), +// "backgroundUrl" to data.getString(CallkitConstants.EXTRA_CALLKIT_BACKGROUND_URL, ""), +// "actionColor" to data.getString(CallkitConstants.EXTRA_CALLKIT_ACTION_COLOR, ""), +// "incomingCallNotificationChannelName" to data.getString( +// CallkitConstants.EXTRA_CALLKIT_INCOMING_CALL_NOTIFICATION_CHANNEL_NAME, +// "" +// ), +// "missedCallNotificationChannelName" to data.getString( +// CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_NOTIFICATION_CHANNEL_NAME, +// "" +// ), +// ) +// val notification = mapOf( +// "id" to data.getInt(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_ID), +// "showNotification" to data.getBoolean(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_SHOW), +// "count" to data.getInt(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_COUNT), +// "subtitle" to data.getString(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_SUBTITLE), +// "callbackText" to data.getString(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_CALLBACK_TEXT), +// "isShowCallback" to data.getBoolean(CallkitConstants.EXTRA_CALLKIT_MISSED_CALL_CALLBACK_SHOW), +// ) +// val forwardData = mapOf( +// "id" to data.getString(CallkitConstants.EXTRA_CALLKIT_ID, ""), +// "nameCaller" to data.getString(CallkitConstants.EXTRA_CALLKIT_NAME_CALLER, ""), +// "avatar" to data.getString(CallkitConstants.EXTRA_CALLKIT_AVATAR, ""), +// "number" to data.getString(CallkitConstants.EXTRA_CALLKIT_HANDLE, ""), +// "type" to data.getInt(CallkitConstants.EXTRA_CALLKIT_TYPE, 0), +// "duration" to data.getLong(CallkitConstants.EXTRA_CALLKIT_DURATION, 0L), +// "textAccept" to data.getString(CallkitConstants.EXTRA_CALLKIT_TEXT_ACCEPT, ""), +// "textDecline" to data.getString(CallkitConstants.EXTRA_CALLKIT_TEXT_DECLINE, ""), +// "extra" to data.getSerializable(CallkitConstants.EXTRA_CALLKIT_EXTRA)!!, +// "missedCallNotification" to notification, +// "android" to android +// ) +// FlutterCallkitIncomingPlugin.sendEvent(event, forwardData) +// } +//} \ No newline at end of file diff --git a/lib/classes/chat_call_kit.dart b/lib/classes/chat_call_kit.dart index da0683f..b739748 100644 --- a/lib/classes/chat_call_kit.dart +++ b/lib/classes/chat_call_kit.dart @@ -106,7 +106,7 @@ class ChatVoipCall { } } - Future declineCall({var payload}) async { + Future declineCall({ payload}) async { IncomingCallModel data = IncomingCallModel.fromJson(jsonDecode(payload)); if (isUserOnline) { @@ -120,7 +120,8 @@ class ChatVoipCall { chatHubConnection = _hc; } } - } else { + } + //else { // Future.delayed(const Duration(seconds: 3), () { // ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); // }); @@ -135,22 +136,22 @@ class ChatVoipCall { // FlutterCallkitIncoming.endAllCalls(); // await _hc.stop(); // } - } + // } - // - // try { - // var response = await platform.invokeMethod( - // 'executeHttpPostRequest', {"currentUserID": data.extra!.callerDetails!.targetUserId, "targetUserID": data.extra!.callerDetails!.currentUserId, "token": data.extra!.loginDetails!.token}); - // print('HTTP POST response: $response'); - // Future.delayed(Duration(seconds: 3), () { - // ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); - // }); - // } on PlatformException catch (e) { - // print('Error invoking method: ${e.message}'); - // } + // + // try { + // var response = await platform.invokeMethod( + // 'executeHttpPostRequest', {"currentUserID": data.extra!.callerDetails!.targetUserId, "targetUserID": data.extra!.callerDetails!.currentUserId, "token": data.extra!.loginDetails!.token}); + // print('HTTP POST response: $response'); + // Future.delayed(Duration(seconds: 3), () { + // ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); + // }); + // } on PlatformException catch (e) { + // print('Error invoking method: ${e.message}'); + // } -//await ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); -// logger.log(Level.error, "API-EVENT-END"); + //await ChatApiClient().callDecline(cUserID: data.extra!.callerDetails!.targetUserId!, tUserID: data.extra!.callerDetails!.currentUserId!, targetUsertoken: data.extra!.loginDetails!.token!); + // logger.log(Level.error, "API-EVENT-END"); } Future makeHub({required IncomingCallModel sessionData}) async { diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 01cdb7c..28bcc80 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -90,10 +90,11 @@ class _LoginScreenState extends State with WidgetsBindingObserver { // if (kReleaseMode) { // checkDeviceSafety(); // } + WidgetsBinding.instance.addObserver(this); if (Platform.isAndroid) { callListeners(); + checkAndNavigationCallingPage(); } - WidgetsBinding.instance.addObserver(this); setupVoIPCallBacks(); } @@ -192,6 +193,7 @@ class _LoginScreenState extends State with WidgetsBindingObserver { Future callListeners() async { try { + print("CallListners Init"); FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async { switch (event!.event) { case Event.actionCallIncoming: @@ -220,14 +222,16 @@ class _LoginScreenState extends State with WidgetsBindingObserver { Utils.saveStringFromPrefs("inComingCallData", "null"); FlutterCallkitIncoming.endAllCalls(); break; + } + print( '${event.toString()}\n'); + }); } on Exception { logger.log(Level.info, "EXCEPTION-ON-EVENTS"); } } - Future moveToCallScreen() async { dynamic calls = await FlutterCallkitIncoming.activeCalls(); if (calls is List) { @@ -246,6 +250,30 @@ class _LoginScreenState extends State with WidgetsBindingObserver { } } + Future getCurrentCall() async { + //check current call from pushkit if possible + var calls = await FlutterCallkitIncoming.activeCalls(); + if (calls is List) { + if (calls.isNotEmpty) { + print('DATA: $calls'); + return calls[0]; + } else { + return null; + } + } + } + + Future checkAndNavigationCallingPage() async { + var currentCall = await getCurrentCall(); + if (currentCall != null && Platform.isAndroid) { + isIncomingCall = true; + Utils.hideLoading(context); + Navigator.push(context, MaterialPageRoute(builder: (context) => StartCallPage())); + } + } + + + @override void dispose() { super.dispose(); diff --git a/pubspec.yaml b/pubspec.yaml index 9cd0866..146400e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -91,6 +91,8 @@ dependencies: draggable_widget: ^2.0.0 flutter_local_notifications: any flutter_callkit_incoming: ^2.0.0+1 +# flutter_callkit_incoming: +# path: ./callKit/flutter_callkit_incoming #firebase_analytics: any workmanager: ^0.5.1