hiennguyen92 / flutter_callkit_incoming

Flutter Callkit Incoming
https://pub.dev/packages/flutter_callkit_incoming
MIT License
180 stars 312 forks source link

not working in terminated state ,when i tap i accept or decline not call listener event ,my code #296

Open ankit-deligence3112 opened 1 year ago

ankit-deligence3112 commented 1 year ago

// ignore_for_file: unnecessary_string_interpolations

import 'dart:async';

import 'package:agora_rtc_engine/agora_rtc_engine.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart';

import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_callkit_incoming/entities/entities.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_ringtone_player/flutter_ringtone_player.dart'; import 'package:hookup4u2/features/calling/ui/screens/call.dart';

import 'package:hookup4u2/features/match/ui/screen/match_page.dart'; import 'package:hookup4u2/models/user_model.dart'; import 'package:provider/provider.dart'; import 'package:rflutter_alert/rflutter_alert.dart';

import '../../../../common/constants/colors.dart';

import '../../../../common/providers/user_provider.dart'; import '../../../../services/notificatiion.dart';

import '../../../notifications/notifications.dart'; import '../../../user/ui/screens/user_profile.dart'; import '../screens/home_page.dart';

Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { debugPrint("Handling a background message: ${message.messageId}");

if (message.data['type'] == 'Call') { channelId = message.data['channel_id']; NotificationData.showCallkitIncoming(message.data['channel_id'], message.data['senderName'], message.data['senderPicture']); } }

String? channelId;

class Tabbar extends StatefulWidget { final bool? isPaymentSuccess; final String? plan; const Tabbar(this.plan, this.isPaymentSuccess, {super.key}); @override TabbarState createState() => TabbarState(); }

//_ class TabbarState extends State { CollectionReference callRef = FirebaseFirestore.instance.collection("calls"); List users = []; int swipedcount = 0; // late final Uuid _uuid; String? currentUuid; String textEvents = "";

bool isPuchased = false; @override void initState() { super.initState();

// when any background message recieve

initFirebase();
listenerEvent(onEvent);

// NotificationData.getCurrentUser();

// when user tap on msg fron terminated state
// FirebaseMessaging.instance.getInitialMessage().then((message) async {
//   debugPrint("RemoteMessage  ${message?.data}");
//   if (message != null) {
//     if (message.data['type'] == 'Call') {
//       var currentCall = await getCurrentCall();
//       if (currentCall != null) {}
//     }
//   } else {}
// });

// Check call when open app from terminated

if (widget.isPaymentSuccess != null && widget.isPaymentSuccess!) {
  WidgetsBinding.instance.addPostFrameCallback((_) async {
    await Alert(
      context: context,
      type: AlertType.success,
      title: "Confirmation".tr().toString(),
      desc: "You have successfully subscribed to our"
          .tr(args: ['${widget.plan}']).toString(),
      buttons: [
        DialogButton(
          onPressed: () => Navigator.pop(context),
          width: 120,
          child: Text(
            "Ok".tr().toString(),
            style: const TextStyle(color: Colors.white, fontSize: 20),
          ),
        )
      ],
    ).show();
  });
}

}

getCurrentCall() async { //check current call from pushkit if possible var calls = await FlutterCallkitIncoming.activeCalls(); if (calls is List) { if (calls.isNotEmpty) { debugPrint('DATA: $calls'); currentUuid = calls[0]['id']; return calls[0]; } else { currentUuid = ""; return null; } } }

Future listenerEvent(Function? callback) async { try { FlutterCallkitIncoming.onEvent.listen((event) async { if (kDebugMode) { print('HOME: $event'); } switch (event!.event) { case Event.actionCallIncoming: break; case Event.actionCallStart: break; case Event.actionCallAccept: debugPrint("callinfo from navigation $channelId"); await callRef.doc(event.body['id']).update({'response': "Pickup"}); await FlutterRingtonePlayer.stop(); checkAndNavigationCallingPage(event.body['id']); break; case Event.actionCallDecline: await FlutterCallkitIncoming.endAllCalls(); await callRef.doc(event.body['id']).update({'response': 'Decline'});

        debugPrint(
            'decilne incoming dart------------------------------------');

        break;
      case Event.actionCallEnded:
        await callRef
            .doc(event.body['id'])
            .update({'response': 'Not-answer'});
        await FlutterCallkitIncoming.endAllCalls();
        break;
      case Event.actionCallTimeout:
        await FlutterCallkitIncoming.endAllCalls();
        await callRef
            .doc(event.body['id'])
            .update({'response': 'Not-answer'});

        debugPrint(
            'decilne incoming dart------------------------------------');
        break;
      case Event.actionCallCallback:
        break;
      case Event.actionCallToggleHold:
        break;
      case Event.actionCallToggleMute:
        break;
      case Event.actionCallToggleDmtf:
        break;
      case Event.actionCallToggleGroup:
        break;
      case Event.actionCallToggleAudioSession:
        break;
      case Event.actionDidUpdateDevicePushTokenVoip:
        break;
      case Event.actionCallCustom:
        break;
    }
    if (callback != null) {
      callback(event.toString());
    }
  });
} on Exception {
  rethrow;
}

}

checkAndNavigationCallingPage(String channelId) async { var currentCall = await getCurrentCall(); if (currentCall != null) { // ignore: use_build_context_synchronously Navigator.push( context, MaterialPageRoute( builder: (context) => CallPage( callType: "Audiocall", channelName: channelId, role: ClientRoleType.clientRoleBroadcaster, ))); } }

initFirebase() async { await Firebase.initializeApp();

FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
  debugPrint(
      'Message title: ${message.notification?.title}, body: ${message.notification?.body}, data: ${message.data}');

  NotificationData.showCallkitIncoming(message.data['channel_id'],
      message.data['senderName'], message.data['senderPicture']);
});
FirebaseMessaging.instance.getToken().then((token) {
  debugPrint('Device Token FCM: $token');
});

}

// Future didChangeAppLifecycleState(AppLifecycleState state) async { // debugPrint(state.toString()); // if (state == AppLifecycleState.resumed) { // //Check call when open app from background // checkAndNavigationCallingPage(channelId!); // } // }

onEvent(event) { if (!mounted) return; setState(() { textEvents += "${event.toString()}\n"; }); }

@override Widget build(BuildContext context) { final userProvider = Provider.of(context, listen: true); debugPrint("user print ${userProvider.currentUser.toString()}"); // Future.microtask(() async { // UserSearchRepo.getAccessItems(); // UserModel currentUser = userProvider.currentUser!; // UserSearchRepo.getMatches(currentUser); // users = await UserSearchRepo.getUserList(currentUser); // debugPrint("cominguser${users.toString()}"); // swipedcount = UserSearchRepo.swipecount; // }); return WillPopScope( onWillPop: _onWillPop, child: Scaffold( body: DefaultTabController( length: 4, initialIndex: widget.isPaymentSuccess != null ? widget.isPaymentSuccess! ? 0 : 1 : 1, child: Scaffold( appBar: AppBar( elevation: 0, backgroundColor: primaryColor, automaticallyImplyLeading: false, title: const TabBar( labelColor: Colors.white, indicatorColor: Colors.white, unselectedLabelColor: Colors.black, isScrollable: false, indicatorSize: TabBarIndicatorSize.label, tabs: [ Tab( icon: Icon( Icons.person, size: 30, ), ), Tab( icon: Icon( Icons.whatshot, ), ), Tab( icon: Icon( Icons.notifications, ), ), Tab( icon: Icon( Icons.message, ), ) ]), ), body: const TabBarView( physics: NeverScrollableScrollPhysics(), children: [ Center( child: ProfilePage(), ), Center(child: Homepage(items: {})), Center(child: Notifications()), Center(child: MatchScreen()), ], )), ), ), ); }

Future _onWillPop() async { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Exit'.tr().toString()), content: Text('Do you want to exit the app?'.tr().toString()), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: Text('No'.tr().toString()), ), TextButton( onPressed: () => SystemChannels.platform.invokeMethod('SystemNavigator.pop'), child: Text('Yes'.tr().toString()), ), ], ); }, ); return true; } }

ArjunBhilare commented 1 year ago

Hey, even I am facing this issue, did you find a workaround?

ankit-deligence3112 commented 1 year ago

no ,not yet

ankit-deligence3112 commented 1 year ago

hey @ArjunBhilare you find any solution ?

hiennguyen92 commented 1 year ago

i think we can't navigate when app kill. so i have to use this check https://github.com/hiennguyen92/flutter_callkit_incoming/blob/6cb1ba422f835fc2482cb5c012cba1ecdb237188/example/lib/main.dart#L87 to open calling page when open app

ankit-deligence3112 commented 1 year ago

i think we can't navigate when app kill. so i have to use this check

https://github.com/hiennguyen92/flutter_callkit_incoming/blob/6cb1ba422f835fc2482cb5c012cba1ecdb237188/example/lib/main.dart#L87

to open calling page when open app

Thanks for your support ,but this function call when app come from background also ,i want to call only when app come from terminated because in foreground and background callkit accept button is working fine

Faisalbutt555 commented 1 year ago

i think we can't navigate when app kill. so i have to use this check

https://github.com/hiennguyen92/flutter_callkit_incoming/blob/6cb1ba422f835fc2482cb5c012cba1ecdb237188/example/lib/main.dart#L87

to open calling page when open app

hi i am facing issue in ios at phone lock state when i try to accept call its not accept call directly when i hot reload it then it pick call and after pick how to handle further functions like add in call mute etc how to handle all in flutter side?

ribalassaf commented 11 months ago

any solutions to this please?

haninhn commented 8 months ago

did find a solution @ribalassaf

Ayush783 commented 8 months ago

This might help - https://medium.com/@Ayush_b58/flutter-callkit-handle-actions-in-the-killed-state-e6f296c603e6

sagar1garg commented 7 months ago

@hiennguyen92 merge @Ayush783's solution in the main branch?

sunilsinghchaudhary00 commented 3 months ago

@hiennguyen92 merge @Ayush783's solution in the main branch?

is ayush solutioin is working when app is terminated can i accept call and get all data needed

hiennguyen92 commented 3 months ago

Ok. I will check and merge it inside next version.

sunilsinghchaudhary00 commented 3 months ago

hey @hiennguyen92 pls have a look on to this while app is in terminated state then accept and declined click is not working pls give us some workaround of it accept it everything is working fine

sagar1garg commented 3 months ago

@hiennguyen92 when is the release with this functionality expected?

sunil-singh-chaudhary commented 3 months ago

@hiennguyen92 when is the release with this functionality expected?

hi till now i have found a workaround you can check it here https://stackoverflow.com/questions/78667613/flutter-callkit-incoming-accept-call-not-working-when-app-is-terminated/78834487