Hello friends, In today’s tutorial we would learn about making a call directly from flutter application. Now how this works is? We have a TextField widget and a button in our UI. Now we have to type number in our flutter app and when we click on the button then it will automatically redirect us to the Phone Dial screen with our number typed also. We are using flutter’s url_launcher pub package in our project to implement this functionality. So in this tutorial we would learn about Example of Dial Phone Number From Flutter App.
Contents in this project Example of Dial Phone Number From Flutter App :-
1. First of all we have to install the url_launcher pub package in our flutter project. So open your flutter project Root directory in Command Prompt or Terminal and execute below command.
1 |
flutter pub add url_launcher |
2. Now we have to manually add Android Dial Intent in our AndroidManifest.xml file. So open Your_Flutter_Project -> android -> app -> src -> main -> AndroidManifest.xml file. and put below Intent code inside it.
1 2 3 4 5 6 |
<queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel" /> </intent> </queries> |
Source Code of my AndroidManifest.xml file after adding above code :-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app2"> <application android:label="app2" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> <queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel" /> </intent> </queries> </manifest> |
3. Now open your project’s main.dart file and import material.dart and url_launcher.dart package.
1 2 |
import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; |
4. Creating our void main runApp() method and here we would call our main MyApp class.
1 |
void main() => runApp(MyApp()); |
5. Creating our main MyApp extends StatelessWidget class. In this class we would call our Dial() class.
1 2 3 4 5 6 7 8 9 10 11 |
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text("Dial Number From Flutter App"), ), body: Center(child: Dial()))); } } |
6. Creating Dial extends StatefulWidget class. In this class we would make DialScreen with createState() method to enable mutable state management.
1 2 3 |
class Dial extends StatefulWidget { DialScreen createState() => DialScreen(); } |
7. Creating our main DialScreen extends State<Dial> class.
1 2 3 4 5 |
class DialScreen extends State<Dial> { } |
8. Creating a TextEditingController named as number. It is used to extract typed data from TextField widget.
1 |
TextEditingController number = TextEditingController(); |
9. Creating a Future type _dialCall() ASYNC function. In this function we would simply get the number from TextField widget and open the Dial screen.
1 2 3 4 5 6 7 8 |
Future<void> _dialCall() async { String phoneNumber = number.text.toString(); final Uri launchUri = Uri( scheme: 'tel', path: phoneNumber, ); await launch(launchUri.toString()); } |
10. Creating Widget Build area -> Here we would make 1 TextField widget and 1 Button widget.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Widget build(BuildContext context) { return Scaffold( body: SafeArea( top: true, child: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), margin: const EdgeInsets.fromLTRB(0, 20, 0, 0), child: TextField( decoration: const InputDecoration( labelText: 'Dial Number', border: OutlineInputBorder(), ), controller: number, keyboardType: TextInputType.number, )), Container( margin: const EdgeInsets.fromLTRB(10, 20, 0, 0), child: ElevatedButton( child: const Text('Call'), onPressed: () => _dialCall(), )) ], ), ))); } |
11. Complete source code for main.dart file :-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text("Dial Number From Flutter App"), ), body: Center(child: Dial()))); } } class Dial extends StatefulWidget { DialScreen createState() => DialScreen(); } class DialScreen extends State<Dial> { TextEditingController number = TextEditingController(); Future<void> _dialCall() async { String phoneNumber = number.text.toString(); final Uri launchUri = Uri( scheme: 'tel', path: phoneNumber, ); await launch(launchUri.toString()); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( top: true, child: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), margin: const EdgeInsets.fromLTRB(0, 20, 0, 0), child: TextField( decoration: const InputDecoration( labelText: 'Dial Number', border: OutlineInputBorder(), ), controller: number, keyboardType: TextInputType.number, )), Container( margin: const EdgeInsets.fromLTRB(10, 20, 0, 0), child: ElevatedButton( child: const Text('Call'), onPressed: () => _dialCall(), )) ], ), ))); } } |
Screenshots :-