Open In App

Making Calls in Flutter

Last Updated : 09 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In this online world, customer care plays a major role in the success of a company. Users are quite satisfied when they converse with the executives through calls. This has forced companies to add phone numbers to their apps for their customers to contact them easily. But dialing those numbers from the app into the default phone app makes it quite cumbersome. So, to improve the user experience, Flutter has come up with a feature where the user can call the other, just with a click.

In Flutter, there are two ways to make a phone call.

  • Launching the Default Phone Dialer App
  • Making Direct Phone Calls (Without Opening Dialer)


Launching the Default Phone Dialer App

In this process, the default phone app will be used to make a call; it will open the app directly, and the number will be automatically filled in the text field.

Steps to Implement Making Calls in Flutter application

Step 1: Create a New Flutter Application

Create a new Flutter application using the command Prompt. To create a new app, write the below command and run it.

flutter create app_name

To know more about it refer this article: Creating a Simple Application in Flutter


Step 2: Adding the Dependency

To add the dependency to the pubspec.yaml file, add url_launcher as a dependency in the dependencies part of the pubspec.yaml file, as shown below:

Dart
dependencies:
     flutter:
       sdk: flutter
     url_launcher: ^6.3.1


Now run the below command in the terminal.

flutter pub get

Step 3: Importing the Dependency

Use the below line of code in the main.dart file, to import the url_launcher dependency :

import 'package:url_launcher/url_launcher.dart';


Step 4: Follow the Below Steps

1. _makingPhoneCall function

Now, let’s create a function that can be called whenever the user clicks a button,that’s linked to a phone number, o make a call.

Dart
_makingPhoneCall() async {
      var _url = Uri.parse("tel:1234567890");
      if (!await launchUrl(_url, mode: LaunchMode.externalApplication)) {
              throw Exception('Could not launch $_url');
      }
}
  • The function is named here as “_makingPhoneCall” and the function is declared as “async”, so that it returns a promise.
  • The “url” variable is assigned with the required phone number, as a string. The "tel:" syntax here before the phone number, makes Flutter realize that the following number is a phone number that has to be opened in the default Phone App. It is declared as a “const”, so that the variable is not changed under any circumstance.
  • If there is a possibility to launch the URL, only then the URL is launched by calling the launch() function with the URL variable as an attribute.
  • Otherwise, it will throw/print a text with the URL value as an error message.


2. Calling the function

The above function can be called when needed inside the program by calling the name of the functions as it is. The example is as follows:

  • This creates a raised button having the text “Call” on it.
  • For the onPressed attribute, we are calling "_makingPhoneCall" so that when the button is pressed, the default Phone app is opened and the phone number in the URL variable is dialed automatically, making it easier for the user.

Complete Source Code

main.dart

Dart
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';


void main() => runApp(const MyApp());

_makingPhoneCall() async {
  var _url = Uri.parse("tel:1234567890");
  if (!await launchUrl(_url, mode: LaunchMode.externalApplication)) {
    throw Exception('Could not launch $_url');
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Geeks for Geeks'),
          backgroundColor: Colors.green,
        ), // AppBar
        body: SafeArea(
          child: Center(
            child: Column(
              children: [
                Container(
                  height: 250.0,
                ),//Container
                const Text(
                  'Welcome to GFG!',
                  style: TextStyle(
                    fontSize: 30.0,
                    color: Colors.green,
                    fontWeight: FontWeight.bold,
                  ),//TextStyle
                ),//Text
                Container(
                  height: 20.0,
                ),
                const Text(
                  'For further Updates',
                  style: TextStyle(
                    fontSize: 20.0,
                    color: Colors.green,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Container(
                  height: 20.0,
                ),
               ElevatedButton(
                  onPressed: _makingPhoneCall,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.green,
                    foregroundColor: Colors.white
                  ),
                  child: const Text('Here'),
                ), // ElevatedButton
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Output:



Making Direct Phone Calls (Without Opening Dialer)

In this process, the specific number will be called directly from our Flutter app, unlike the previous method, which opens the default phone app on your mobile device.

Steps to Implement Making Calls in Flutter application

Step 1: Create a New Flutter Application

Create a new Flutter application using the command Prompt. To create a new app, write the below command and run it.

flutter create app_name

To know more about it refer this article: Creating a Simple Application in Flutter


Step 2: Adding the Dependency

To add the dependency to the pubspec.yaml file, add direct_phone_call as a dependency in the dependencies part of the pubspec.yaml file, as shown below:

Dart
dependencies:
     flutter:
       sdk: flutter
     direct_phone_call: ^1.0.0


Now run the below command in the terminal.

flutter pub get

Step 3: Importing the Dependency

Use the below line of code in the main.dart file, to import the direct_phone_call dependency :

import 'package:direct_phone_call/direct_phone_call.dart'; 


Step 4: Method to make a phone call

Dart
// Method to make a phone call
Future<void> _makeACall() async {
    // Dismiss the keyboard
    FocusScope.of(context).unfocus(); 
    // Validate the form
    if (_formKey.currentState!.validate()) { 
        bool isCalled = false;
        try {
            // Attempt to make the phone call
            isCalled = await _directPhoneCallPlugin.callNumber(
                number: _phoneNoController.text);
        } catch (e) {
            // Log any exceptions
            log('Exception : ${e}'); 
        }
    }
}


Complete Source code

main.dart:

Dart
// For logging purposes
import 'dart:developer';
// Flutter UI framework
import 'package:flutter/material.dart';
// For asynchronous programming
import 'dart:async';
// For platform-specific services
import 'package:flutter/services.dart';
// Plugin for making direct phone calls
import 'package:direct_phone_call/direct_phone_call.dart';

void main() {
  // Entry point of the app
  runApp(const MyApp());
}

// Main application widget
class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

// State class for MyApp
class _MyAppState extends State<MyApp> {
  // Key for form validation
  final GlobalKey<FormState> _formKey = GlobalKey();
  // Controller for phone number input
  final TextEditingController _phoneNoController = TextEditingController();
  // Instance of the phone call plugin
  final _directPhoneCallPlugin = DirectPhoneCall();

  @override
  void dispose() {
    super.dispose(); // Dispose resources
    _phoneNoController.dispose(); // Dispose the controller
  }

  // Method to make a phone call
  Future<void> _makeACall() async {
    // Dismiss the keyboard
    FocusScope.of(context).unfocus();
    // Validate the form
    if (_formKey.currentState!.validate()) {
      bool isCalled = false;
      try {
        // Attempt to make the phone call
        isCalled = await _directPhoneCallPlugin.callNumber(
            number: _phoneNoController.text);
      } catch (e) {
        // Log any exceptions
        log('Exception : ${e}');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Disable debug banner
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Make a call'),
          backgroundColor: Colors.green,
          // App bar text color
          foregroundColor: Colors.white,
        ),
        body: Form(
          key: _formKey, // Assign form key
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                const SizedBox(
                  height: 24,
                ),
                TextFormField(
                  controller: _phoneNoController, // Assign controller
                  style: const TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w500,
                  ),
                  validator: (value) {
                    // Validation logic
                    if (value == null || value.isEmpty) {
                      // Error for empty input
                      return 'Please fill phone number';
                    }
                    if (value.isNotEmpty && value.length < 7) {
                      // Error for invalid number
                      return 'Invalid number';
                    }
                    // Input is valid
                    return null;
                  },
                  keyboardType: TextInputType.phone, // Set keyboard type
                  textInputAction: TextInputAction.done, // Set action button
                  decoration: InputDecoration(
                    fillColor: Colors.white, // Input field background color
                    hintText: 'Phone number', // Placeholder text
                    hintStyle: const TextStyle(
                      color: Colors.black26,
                      fontSize: 12,
                      fontWeight: FontWeight.w400,
                    ),
                    prefixIcon: Icon(
                      Icons.local_phone_rounded,
                      color: Colors.green.shade800,
                      size: 18,
                    ), // Phone icon
                    contentPadding: EdgeInsets.zero, // Remove padding
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10), // Rounded border
                      borderSide: const BorderSide(
                        color: Colors.black38,
                      ),
                    ),
                    enabledBorder: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                      borderSide: const BorderSide(
                        color: Colors.black38,
                      ),
                    ),
                    focusedBorder: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                      borderSide: const BorderSide(
                        color: Colors.green,
                        width: 1.5,
                      ),
                    ),
                  ),
                  onFieldSubmitted: (val) =>
                      _makeACall(), // Call method on submit
                ),
                const SizedBox(
                  height: 12,
                ), // Add vertical spacing
                ElevatedButton(
                  onPressed: () => _makeACall(), // Call method on button press
                  style: ButtonStyle(
                    backgroundColor: WidgetStatePropertyAll(
                      Colors.green.shade900,
                    ), // Button background color
                    minimumSize: const WidgetStatePropertyAll(
                      Size(100, 35),
                    ), // Button size
                  ),
                  child: Container(
                    child: const Text(
                      'Call', // Button text
                      style: TextStyle(
                        color: Colors.white, // Text color
                        fontSize: 13, // Text size
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}


Output:



Next Article
Article Tags :

Similar Reads