In this Flutter tutorial, we’ll learn how to get Flutter contacts list. We’ll fetch and display contact’s name, image and phone number. We’ll also redirect user to make a call, if the user taps on item(contact) of list. Everything will be discussed step by step using a practical code example in order for better understanding.
So what are we waiting for? Let’s jump right into its implementation phase.
Introduction: Flutter Contacts List
We’ll fetch contact’s data from phone and display it inside Flutter app. We’ll do the required settings for both android and IOS. We’ll import all the necessary packages as well.
Flutter contacts package is used to read, delete, update and delete contacts from device. In this tutorial, we’ll just learn how to read/fetch contact’s data.
We’ll also allow the user to tap on any specific item of list(contact) and it’ll navigate the user to make a call.
Implementing Flutter Contacts List (Step By Step)
Follow below steps in order to understand the complete process of fetching and displaying contacts data in Flutter app.
Step 1: Import Packages (Flutter Contacts, URL Launcher, Permission Handler)
flutter_contacts: ^1.1.5+1 url_launcher: ^6.1.7 permission_handler: ^10.2.0
Flutter contacts – Its used to fetch Flutter contacts list in both android and IOS.
URL launcher – In our case, it will be used to redirect user to make a call.
Permission handler – Its used to allow/deny access to phone’s data.
These three packages are necessary to fetch contacts and redirect user to make a call. Import them in your pubspec.yaml file. See below image:
Links to latest versions of these 3 packages are listed below.
- Flutter contacts – latest version
- URL launcher – latest version
- Permission handler – latest version
Step 2: Required Setup
For Android
Setup for android is given below.
1. AndroidX and Enable Jetifier
Set the androidX and enable jetifier to true, if not specified. The path is android/gradle.properties.
android.useAndroidX=true android.enableJetifier=true
2. Compile SDK Version
Set the compile SDK version to more than 28. In our case, its 33. The path is android/app/build.gradle.
compileSdkVersion 33
3. Contact Permissions in Android Manifest XML
Add permissions to access device contacts information. The path is android/app/src/main/AndroidManifest.xml.
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" />
For IOS
<key>NSContactsUsageDescription</key> <string>Reason we need access to the contact list</string>
Step 3: Coding
1. Import Statements: Flutter Contacts and URL Launcher
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:url_launcher/url_launcher_string.dart'; // use it if you want to redirect user to make a call
2. Function: Fetch and Store Flutter Contacts List
There are two methods through which we can fetch phone’s contact info. These are listed below:
Method 1: Partial Fetch
List<Contact> contactsList = await FlutterContacts.getContacts();
Method 2: Full Fetch
List<Contact> contactsList = await FlutterContacts.getContacts( withProperties: true, withPhoto: true);
In our case, we’ll be using the second method which will fetch contact’s photo as well.
List<Contact>? contactsList; // fetched contact's data will be stored in this list
void getPhoneData() async { if (await FlutterContacts.requestPermission()) { contactsList = await FlutterContacts.getContacts( withProperties: true, withPhoto: true); } setState(() {}); }
We can trigger the function using a Flutter button as well. But in our case, we’ll be using the init state and inside it, we’ll call this function. Reason is that we want it to show the list of contacts whenever the screen loads. So when this screen loads, then it’ll ask the user for permission and if granted, then it’ll fetch the contact’s data.
3. Display Data (Name, Number, Picture)
We’ve displayed the fetched data inside Flutter container widgets that are returned by list view builder.
The complete source code will be provided in the end. In the meantime, we’ll just see the logical part.
We’ve specified a condition that if the list of contact’s data is empty then show Flutter circular progress indicator. If not, then display Flutter listview builder. See below:
contactsList == null ? show circular progress indicator : show list view builder
We’ve specified the length of list view builder to be the length of contact list items. See below:
itemCount: contactsList!.length
Display Images
We’ve used the below code to fetch available contact’s images. See below:
import 'dart:typed_data'; // for Uint8List
Uint8List? image = contactsList![index].photo;
It’ll store the available contact’s images. If the image is not available then it’ll show null.
As it’s used inside the list view builder so [index] is used to fetch items from list(contactsList) using indexing method.
In order to display the stored images, we’ve to use memory image. See below code:
MemoryImage(image!)
We’ve created a logic which will check if the image data is null then show the person icon. If not, then display image. Code for that will be available in the complete source code section.
Display Phone Numbers
We’ve created a logic that’ll store phone number in a string, if available. If not, then it’ll store double colons(–) as string. Its because sometimes we save the contact using email or some other info without specifying phone number. See below:
String num = (contactsList![index].phones.isNotEmpty) ? (contactsList![index].phones.first.number) : "--";
It’s a simple if else condition which will check if the phone number is not empty then store the specified number, else store (—).
In order to display it, we’ve used the Flutter text widget. See below:
Text(num) // you can decorate the text using text style
Display Names
In order to display names, we’ve used the text widget. See below:
Text(contactsList![index].name.first) // its used to display first name
contactsList![index].name.last // get last name contactsList![index].displayname // get full name contactsList![index].emails.first.address // get email address - try it and share your experience with us co contactsList![index].photo // get photo
Make A Call
We’ve used URL launcher which will navigate us to our device phone call section with the specified number(if available), whenever we click on any specified item of list. See below:
if (contactsList![index].phones.isNotEmpty) { launchUrlString('tel: ${num}'); }
So this is how we can easily fetch and display phone contact’s data. The complete source code is provided in the below section.
Fetch and Display Flutter Contacts List Source Code
import 'dart:typed_data'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp(debugShowCheckedModeBanner: false, home: HomePage()); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { List<Contact>? contactsList; void getPhoneData() async { if (await FlutterContacts.requestPermission()) { contactsList = await FlutterContacts.getContacts( withProperties: true, withPhoto: true); } setState(() {}); } @override void initState() { getPhoneData(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( body: contactsList == null ? Center( child: CircularProgressIndicator(), ) : ListView.builder( itemCount: contactsList!.length, itemBuilder: (context, index) { Uint8List? image = contactsList![index].photo; String num = (contactsList![index].phones.isNotEmpty) ? (contactsList![index].phones.first.number) : "--"; return GestureDetector( onTap: () { if (contactsList![index].phones.isNotEmpty) { launchUrlString('tel: ${num}'); } }, child: Container( height: 70, width: double.infinity, margin: EdgeInsets.all(10), padding: EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( blurRadius: 5, spreadRadius: 1, offset: Offset(2, 2), color: Colors.grey.shade300) ]), child: Row( children: [ (contactsList![index].photo == null) ? const CircleAvatar(child: Icon(Icons.person)) : CircleAvatar( backgroundImage: MemoryImage(image!)), SizedBox( width: 20, ), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( contactsList![index].displayName, style: TextStyle( fontSize: 18, fontWeight: FontWeight.w500), ), Text(num), ], ) ], ), ), ); }), ); } }
Conclusion
In conclusion, hope you now have a detailed practical knowledge of how to properly fetch and display Flutter contacts list. Don’t hesitate to share your amazing thoughts regarding this post.
We’d be very glad to see you visit our other tutorials on Flutter app development. Thank you for reading this article.