flutter_voip_kit 0.0.6 copy "flutter_voip_kit: ^0.0.6" to clipboard
flutter_voip_kit: ^0.0.6 copied to clipboard

Use iOS CallKit and Android's Telecom library to create and receive calls with native functionality. e.g. Calls pop up on user's lock screen.

example/lib/main.dart

import 'dart:developer' as dev;
import 'dart:math';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_voip_kit/call.dart';
import 'package:flutter_voip_kit/flutter_voip_kit.dart';
import 'package:uuid/uuid.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Call> calls = [];
  bool hasPermission = false;
  bool callShouldFail = false;

  @override
  void initState() {
    super.initState();

    FlutterVoipKit.init(
        callStateChangeHandler: callStateChangeHandler,
        callActionHandler: callActionHandler);

    checkPermissionsUntilGranted();

    //listens to when call list is updated
    FlutterVoipKit.callListStream.listen((allCalls) {
      setState(() {
        calls = allCalls;
      });
    });
  }

  Future<bool> callStateChangeHandler(call) async {
    dev.log("widget call state changed lisener: $call");
    setState(
        () {}); //calls states have been updated, setState so ui can reflect that

    //it is important we perform logic and return true/false for every CallState possible
    switch (call.callState) {
      case CallState
          .connecting: //simulate connection time of 3 seconds for our VOIP service
        dev.log("--------------> Call connecting");
        await Future.delayed(const Duration(seconds: 3));
        return true;
      case CallState
          .active: //here we would likely begin playig audio out of speakers
        dev.log("--------> Call active");
        return true;
      case CallState.ended: //end audio, disconnect
        dev.log("--------> Call ended");
        await Future.delayed(const Duration(seconds: 1));
        return true;
      case CallState.failed: //cleanup
        dev.log("--------> Call failed");
        return true;
      case CallState.held: //pause audio for specified call
        dev.log("--------> Call held");
        return true;
      default:
        return false;
    }
  }

  Future<bool> callActionHandler(Call call, CallAction action) async {
    dev.log("widget call action handler: $call");
    setState(
        () {}); //calls states have been updated, setState so ui can reflect that

    //it is important we perform logic and return true/false for every CallState possible
    switch (action) {
      case CallAction.muted:
        //EXAMPLE: here we would perform the logic on our end to mute the audio streams between the caller and reciever
        return true;
        break;
      default:
        return false;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Voip Kit Example'),
      ),
      body: !hasPermission
          ? Center(
              child: ElevatedButton(
                child: Text("Grant Phone Permissions"),
                onPressed: () {
                  FlutterVoipKit.checkPermissions(openSettings: true)
                      .then((value) => setState(() {
                            hasPermission = value;
                          }));
                },
              ),
            )
          : SafeArea(
              child: Column(
                children: [
                  ElevatedButton(
                    child: Text("Simlualate incoming call"),
                    onPressed: () {
                      Future.delayed(const Duration(seconds: 2)).then((value) {
                        FlutterVoipKit.reportIncomingCall(
                            handle: "${Random().nextInt(10)}" * 9,
                            uuid: Uuid().v4());
                      });
                    },
                  ),
                  ElevatedButton(
                    child: Text("Start Call outgoing call"),
                    onPressed: () {
                      FlutterVoipKit.startCall(
                        "${Random().nextInt(10)}" * 9,
                      );
                    },
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemBuilder: (context, index) {
                        final call = calls[index];
                        return Container(
                          color: call.callState == CallState.active
                              ? Colors.green[300]
                              : call.callState == CallState.held
                                  ? Colors.yellow[800]
                                  : (call.callState == CallState.connecting
                                      ? Colors.yellow[200]
                                      : Colors.red),
                          padding: EdgeInsets.all(16.0),
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              Expanded(
                                child: Text("Number: ${call.address}"),
                              ),
                              if (call.callState == CallState.connecting)
                                CircularProgressIndicator(),
                              if (call.callState != CallState.connecting &&
                                  call.callState != CallState.incoming)
                                ElevatedButton(
                                  onPressed: () {
                                    call.hold(
                                        onHold: !(call.callState ==
                                            CallState.held));
                                  },
                                  child: Text(call.callState == CallState.held
                                      ? "Resume"
                                      : "Hold"),
                                ),
                              if (call.callState == CallState.active) ...[
                                IconButton(
                                  icon: Icon(
                                    Icons.phone_disabled_sharp,
                                    size: 30,
                                    color: Colors.red,
                                  ),
                                  onPressed: () {
                                    call.end();
                                  },
                                ),
                                IconButton(
                                    icon: Icon(
                                      call.muted ? Icons.mic : Icons.mic_off,
                                      size: 30,
                                    ),
                                    onPressed: () {
                                      call.mute(muted: !call.muted);
                                    })
                              ]
                            ],
                          ),
                        );
                      },
                      itemCount: calls.length,
                    ),
                  )
                ],
              ),
            ),
    );
  }

  void checkPermissionsUntilGranted() {
    Future.delayed(const Duration(milliseconds: 100)).then((value) async {
      //delay to wait for init state to be done
      hasPermission =
          await FlutterVoipKit.checkPermissions(openSettings: false);
      bool first = true; //dont bring to settings first time
      while (!hasPermission) {
        await showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text("No Permissions"),
              content: Text(
                  "You allow this app to use your phone and add it to phone list in settings."),
              actions: <Widget>[
                ElevatedButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text("Ok"),
                )
              ],
            );
          },
        );

        hasPermission =
            await FlutterVoipKit.checkPermissions(openSettings: !first);
        first = false;
        if (!hasPermission) {
          await Future.delayed(const Duration(seconds: 1));
        }
      }
      setState(() {});
    });
  }
}
copied to clipboard
43
likes
150
points
51
downloads

Publisher

unverified uploader

Weekly Downloads

2024.09.26 - 2025.04.10

Use iOS CallKit and Android's Telecom library to create and receive calls with native functionality. e.g. Calls pop up on user's lock screen.

Homepage

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on flutter_voip_kit