Hafiz Hamza Jamil
Hafiz Hamza Jamil

Reputation: 11

Incoming call to subscriber is showing and ringing even the publisher ends the call before the subscriber attends the call

when the publisher make a call and the subscriber mobile rings and the incoming call notification is showing and suddenly the publisher ends the call. Subscriber mobile is still ringing and incoming call notification is showing for 20 seconds. I want that that as the publisher end the call before the subscriber attends the call the notification and ringing will be dismissed.

    typedef void CallDeclineCallback();

class LocalNotificationService {
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();
  static LocalNotificationService? _instance;
  VoIPData? _currentPayload;

  factory LocalNotificationService() {
    if (_instance == null) {
      _instance = LocalNotificationService._internal();
    }
    return _instance!;
  }

  CallDeclineCallback? onCallDecline;

  void _handleCallDecline() {
    if (onCallDecline != null) {
      onCallDecline!();
    }
  }

  LocalNotificationService._internal();

  void _storePayload(VoIPData payload) {
    print('Storing payload: $payload');
    print('CallUUID: ${payload.callId}');
    _currentPayload = payload;
  }

  VoIPData? getCurrentCallPayload() {
    return _currentPayload;
  }

  Future<void> init() async {
    CallKeep.instance.onEvent.listen((event) async {
      if (event == null) return;
      switch (event.type) {
        case CallKeepEventType.callAccept:
          final data = event.data as CallKeepCallData;
          print('call answered: ${data.toMap()}');
          var callID = data.uuid;
          var dataWithMap = data.toMap();
          var userName = dataWithMap['callerName'];
          var extra = dataWithMap['extra'];
          print("UserName below");
          print(userName);

          FirebaseService().getTokenForCall(callID);

          String? token = extra['token'];
          String? sessionID = extra['sessionID'];
          print("Token: $token and $sessionID for call $callID");
          print(
              "NavigatorKey current state: ${NavigationService.instance.navigationKey.currentState}");

          if (token != null && sessionID != null && callID != null) {
            NavigationService.instance.pushReplacementNamed(
              AppRoute.callingPage,
              args: {
                'token': token!,
                'sessionID': sessionID!,
                'callUUID': callID!,
                'callerName': userName,
              },
            );
          } else {
            Fluttertoast.showToast(
              msg:
                  'Token, sessionID or CallUUID is missing. Please try again later.',
              toastLength: Toast.LENGTH_SHORT,
              gravity: ToastGravity.BOTTOM,
            );
          }

          break;
        case CallKeepEventType.callDecline:
          final data = event.data as CallKeepCallData;
          print('call declined: ${data.toMap()}');

          _handleCallDecline();
          NotificationServices().sendNotification(
              "Declined Call",
              "You're out of the queue. Please mark yourself available again.");
          break;
        case CallKeepEventType.missedCallback:
          final data = event.data as CallKeepCallData;
          break;
        default:
          print(
              "Not sure which CallKeep datatype is for LocalNotitication: ${event.type}");
          break;
      }
    });
  }

  Future<void> displayIncomingCall(VoIPData notificationData) async {
    print("displayIncomingCall with payload ${notificationData}");
    _storePayload(notificationData);
    final config = CallKeepIncomingConfig(
      uuid: notificationData.callId,
      callerName: '${notificationData.body}',
      appName: 'Shop AR Online',
      handle: 'Video',
      hasVideo: true,
      duration: 30000,
      acceptText: 'Accept',
      declineText: 'Decline',
      missedCallText: 'Missed video call',
      callBackText: 'Call back',
      extra: <String, dynamic>{
        'token': notificationData.customData.token,
        'sessionID': notificationData.customData.sessionId
      },
      headers: <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
      androidConfig: CallKeepAndroidConfig(
        logo: "ic_logo",
        showCallBackAction: false,
        showMissedCallNotification: true,
        ringtoneFileName: 'system_ringtone_default',
        accentColor: '#0955fa',
        backgroundUrl: 'assets/background.jpeg',
        incomingCallNotificationChannelName: 'Incoming Calls',
        missedCallNotificationChannelName: 'Missed Calls',
      ),
      iosConfig: CallKeepIosConfig(
        iconName: 'CallKitLogo',
        handleType: CallKitHandleType.generic,
        isVideoSupported: true,
        maximumCallGroups: 2,
        maximumCallsPerCallGroup: 1,
        audioSessionActive: true,
        audioSessionPreferredSampleRate: 44100.0,
        audioSessionPreferredIOBufferDuration: 0.005,
        supportsDTMF: true,
        supportsHolding: true,
        supportsGrouping: false,
        supportsUngrouping: false,
        ringtoneFileName: 'system_ringtone_default',
      ),
    );
    await CallKeep.instance.displayIncomingCall(config);
  }

  Future<CallKeepCallData?> getCurrentCall() async {
    print("Get Current Call called");
    var calls = await CallKeep.instance.activeCalls();
    if (calls.isNotEmpty) {
      print('Active Calls: $calls');
      return calls.first;
    } else {
      print("No active calls available");
      return null;
    }
  }

  Future<void> dismissAllNotifications() async {
    await flutterLocalNotificationsPlugin.cancelAll();
  }
}

Upvotes: 0

Views: 29

Answers (0)

Related Questions