HOW-TO

How to fetch Contacts in Xamarin?

We know that Xamarin is a platform that enables fantastic mobile app developments. With Material visual support in Xamarin forms, you could probably create an impeccable design, handling the layout and look of an app. In this blog, we will create a project in Xamarin forms to fetch contacts with a search bar option.

With any mobile app development, there is one common thing that permit access to read the phone contacts. Here some plugins are available for getting the phone contacts you have to make sure that Plugin.CurrentActivity and Acr.UserDialogs packages are installed. You can also apply Material design rule in Xamarin.Forms applications.

The following step shows how to fetch phone contacts.

Step: 1

Open Visual Studio and select Xamarin project.

After selecting Xamarin forms, give it the appropriate name and select Blank App for Android and iOS platforms.

Step: 2

First, create a Model.

 

GetContact.cs

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace FetchContact.Model

{

public class GetContact

{

public string NameofContact { get; set; }

public string ImageofContact { get; set; }

public string[] Emailsofperson { get; set; }

public string[] Numberofperson { get; set; }

}

}

 

Step: 3

 

Create an Interface.

 

IGetContactServices.cs

 

using FetchContact.Model;

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

 

namespace FetchContact.Service

{

public class IGetContactServices : EventArgs

{

public GetContact getContact { get; }

public IGetContactServices(GetContact contact)

{

getContact = contact;

}

}

public interface IContacts

{

event EventHandler<IGetContactServices> OnContactLoad;

bool IsLoading { get; }

Task<IList<GetContact>> RetrieveContacts(CancellationToken? token = null);

}

}

 

Step: 4

 

After creating the interface open AndroidManifest.xml in the Android project and add the below permission.

 

<uses-permission android:name=”android.permission.READ_CONTACTS” />

 

Step: 5

 

After adding the user permission, add the implementation for the contact service in the Android project.

 

AndroidContactService.cs

 

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Threading;

using System.Threading.Tasks;

using Acr.UserDialogs;

using Android;

using Android.App;

using Android.Content;

using Android.Content.PM;

using Android.Database;

using Android.Provider;

using Android.Runtime;

using Android.Support.V4.App;

using FetchContact.Model;

using FetchContact.Service;

using Plugin.CurrentActivity;

 

namespace FetchContact.Droid.Services

{

public class AndroidContactsService : IContacts

{

const string Thumbnail = “thumbIcon”;

bool stopLoad = false;

static TaskCompletionSource<bool> contactPermission;

public string TAG

{

get

{

return “MainActivity”;

}

}

bool _isLoading = false;

public bool IsLoading => _isLoading;

 

public const int RequestContacts = 1239;

static string[] PermissionsContact = {

Manifest.Permission.ReadContacts

};

 

public event EventHandler<IGetContactServices> OnContactLoad;

 

async void RequestContactsPermissions()

{

if (ActivityCompat.ShouldShowRequestPermissionRationale(CrossCurrentActivity.Current.Activity, Manifest.Permission.ReadContacts)

|| ActivityCompat.ShouldShowRequestPermissionRationale(CrossCurrentActivity.Current.Activity, Manifest.Permission.WriteContacts))

{

 

await UserDialogs.Instance.AlertAsync(“Permission”, “Set the permission”, “Ok”);

}

else

{

ActivityCompat.RequestPermissions(CrossCurrentActivity.Current.Activity, PermissionsContact, RequestContacts);

}

}

public static void RqstPermissionsData(int rqstpermission, string[] permissions, [GeneratedEnum] Permission[] grants)

{

if (rqstpermission == AndroidContactsService.RequestContacts)

{

if (PermissionUtil.VerifyPermissions(grants))

{

contactPermission.TrySetResult(true);

}

else

{

contactPermission.TrySetResult(false);

}

 

}

}

 

public async Task<bool> RequestPermission()

{

contactPermission = new TaskCompletionSource<bool>();

if (Android.Support.V4.Content.ContextCompat.CheckSelfPermission(CrossCurrentActivity.Current.Activity, Manifest.Permission.ReadContacts) != (int)Permission.Granted

|| Android.Support.V4.Content.ContextCompat.CheckSelfPermission(CrossCurrentActivity.Current.Activity, Manifest.Permission.WriteContacts) != (int)Permission.Granted)

{

RequestContactsPermissions();

}

else

{

contactPermission.TrySetResult(true);

}

 

return await contactPermission.Task;

}

 

public async Task<IList<GetContact>> RetrieveContacts(CancellationToken? cancelToken = null)

{

stopLoad = false;

 

if (!cancelToken.HasValue)

cancelToken = CancellationToken.None;

 

var taskCompletionSource = new TaskCompletionSource<IList<GetContact>>();

 

cancelToken.Value.Register(() =>

{

stopLoad = true;

taskCompletionSource.TrySetCanceled();

});

 

_isLoading = true;

 

var task = LoadContacts();

 

var completedTask = await Task.WhenAny(task, taskCompletionSource.Task);

_isLoading = false;

 

return await completedTask;

}

async Task<IList<GetContact>> LoadContacts()

{

IList<GetContact> contacts = new List<GetContact>();

var hasPermission = await RequestPermission();

if (hasPermission)

{

var uri = ContactsContract.Contacts.ContentUri;

var ctx = Application.Context;

await Task.Run(() =>

{

var cursor = ctx.ApplicationContext.ContentResolver.Query(uri, new string[]

{

ContactsContract.Contacts.InterfaceConsts.Id,

ContactsContract.Contacts.InterfaceConsts.DisplayName,

ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri

}, null, null, $”{ContactsContract.Contacts.InterfaceConsts.DisplayName} ASC”);

if (cursor.Count > 0)

{

while (cursor.MoveToNext())

{

var contact = CreateContact(cursor, ctx);

 

if (!string.IsNullOrWhiteSpace(contact.NameofContact))

{

OnContactLoad?.Invoke(this, new IGetContactServices(contact));

contacts.Add(contact);

}

 

if (stopLoad)

break;

}

}

});

 

}

return contacts;

 

}

 

GetContact CreateContact(ICursor cursor, Context ctx)

{

var contactId = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.Id);

 

var numbers = GetNumbers(ctx, contactId);

var emails = GetEmails(ctx, contactId);

 

var uri = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri);

string path = null;

if (!string.IsNullOrEmpty(uri))

{

try

{

using (var stream = Android.App.Application.Context.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(uri)))

{

path = Path.Combine(Path.GetTempPath(), $”{Thumbnail}-{Guid.NewGuid()}”);

using (var str = new FileStream(path, FileMode.Create))

{

stream.CopyTo(str);

str.Close();

}

 

stream.Close();

}

 

 

}

catch (Exception ex)

{

System.Diagnostics.Debug.WriteLine(ex);

}

 

}

var contact = new GetContact

{

NameofContact = GetString(cursor, ContactsContract.Contacts.InterfaceConsts.DisplayName),

Emailsofperson = emails,

ImageofContact = path,

Numberofperson = numbers,

};

 

return contact;

}

 

 

string[] GetNumbers(Context ctx, string contactId)

{

var key = ContactsContract.CommonDataKinds.Phone.Number;

 

var cursor = ctx.ApplicationContext.ContentResolver.Query(

ContactsContract.CommonDataKinds.Phone.ContentUri,

null,

ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + ” = ?”,

new[] { contactId },

null

);

 

return ReadCursorItems(cursor, key)?.ToArray();

}

 

string[] GetEmails(Context ctx, string contactId)

{

var key = ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data;

 

var cursor = ctx.ApplicationContext.ContentResolver.Query(

ContactsContract.CommonDataKinds.Email.ContentUri,

null,

ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId + ” = ?”,

new[] { contactId },

null);

 

return ReadCursorItems(cursor, key)?.ToArray();

}

 

IEnumerable<string> ReadCursorItems(ICursor cursor, string key)

{

while (cursor.MoveToNext())

{

var value = GetString(cursor, key);

yield return value;

}

 

cursor.Close();

}

 

string GetString(ICursor cursor, string key)

{

return cursor.GetString(cursor.GetColumnIndex(key));

}

 

}

}

 

Step: 6

 

Now, add one more class in the Android project to handle permissions.

 

PermissionUtil.cs

 

using Android.Content.PM;

 

namespace FetchContact.Droid

{

public static class PermissionUtil

{

public static bool VerifyPermissions(Permission[] grant)

{

if (grant.Length < 1)

return false;

 

foreach (Permission result in grant)

{

if (result != Permission.Granted)

{

return false;

}

}

return true;

}

}

}

 

Step: 7

In MainActivity class, we can add the RequestPermission method and also use contact service.

Step: 8

Now, create a view model in the main project and use contact services.

MainViewModel.cs

using FetchContact.Model;

using FetchContact.Service;

using System;

using System.Collections;

using System.Collections.ObjectModel;

using System.ComponentModel;

using System.Linq;

using System.Threading.Tasks;

 

namespace FetchContact.ViewModel

{

public class MainViewModel : INotifyPropertyChanged

{

IContacts _contactService;

 

public event PropertyChangedEventHandler PropertyChanged;

 

public string Title => “Contacts”;

 

public string SearchContactText { get; set; }

public ObservableCollection<GetContact> Contacts { get; set; }

public ObservableCollection<GetContact> ListContacts

{

get

{

return string.IsNullOrEmpty(SearchContactText) ? Contacts : new ObservableCollection<GetContact>(Contacts?.ToList()?.Where(s => !string.IsNullOrEmpty(s.NameofContact) && s.NameofContact.ToLower().Contains(SearchContactText.ToLower())));

}

}

public MainViewModel(IContacts contactService)

{

_contactService = contactService;

Contacts = new ObservableCollection<GetContact>();

Xamarin.Forms.BindingBase.EnableCollectionSynchronization(Contacts, null, ObservableCollection);

_contactService.OnContactLoad += OnContactLoaded;

LoadContacts();

}

void ObservableCollection(IEnumerable collection, object context, Action accessMethod, bool writeAccess)

{

lock (collection)

{

accessMethod?.Invoke();

}

}

 

private void OnContactLoaded(object sender, IGetContactServices e)

{

Contacts.Add(e.getContact);

}

async Task LoadContacts()

{

try

{

await _contactService.RetrieveContacts();

}

catch (TaskCanceledException)

{

Console.WriteLine(“Something Went Wrong.”);

}

}

 

}

}

 

Step: 9

Add contact service in App.Xaml.cs file.

App.Xaml.cs

public partial class App : Application

{

IContacts _contactsService;

public App(IContacts contactsService)

{

_contactsService = contactsService;

InitializeComponent();

 

MainPage = new NavigationPage(new MainPage(_contactsService));

}

 

Step: 10

 

All steps are done now, we can create a page for display contacts. Using listview we can bind all contacts and also use a search bar for searching.

 

MainPage.Xaml

 

<?xml version=”1.0″ encoding=”utf-8″ ?>

<ContentPage xmlns=”http://xamarin.com/schemas/2014/forms”

xmlns:x=”http://schemas.microsoft.com/winfx/2009/xaml”>

<ContentPage.Content>

<StackLayout>

<SearchBar x:Name=”SearchContact”

HeightRequest=”40″

Text=”{Binding SearchContactText}” />

<ListView   ItemsSource=”{Binding ListContacts}”

HasUnevenRows=”True”>

<ListView.ItemTemplate>

<DataTemplate>

<ViewCell>

<StackLayout Padding=”10″

Orientation=”Horizontal”>

<Image  Source=”{Binding ImageofContact}”

VerticalOptions=”Center”

x:Name=”image”

Aspect=”AspectFit”

HeightRequest=”60″/>

<StackLayout VerticalOptions=”Center”>

<Label Text=”{Binding NameofContact}”

FontAttributes=”Bold”/>

<Label Text=”{Binding Numberofperson[0]}”/>

<Label Text=”{Binding Emailsofperson[0]}”/>

</StackLayout>

</StackLayout>

</ViewCell>

</DataTemplate>

</ListView.ItemTemplate>

</ListView>

</StackLayout>

</ContentPage.Content>

</ContentPage>

 

MainPage.Xaml.cs

 

using FetchContact.Service;

using FetchContact.ViewModel;

using System.ComponentModel;

using Xamarin.Forms;

 

namespace FetchContact

{

[DesignTimeVisible(false)]

public partial class MainPage : ContentPage

{

public MainPage(IContacts services)

{

BindingContext = new MainViewModel(services);

InitializeComponent();

}

}

}

Output:

Conclusion

In this blog, we have discussed how to fetch contacts on Android. For fetching the contacts, you need to permit access to your phone contact and also need to install Plugin.CurrentActivity and Acr.UserDialogs packages in the Android project.

Author Bio: Vinod Satapara – Technical Director, iFour Technolab Pvt. Ltd.

Technocrat and entrepreneur with years of experience building large scale enterprise web, cloud and mobile applications using latest technologies like ASP.NET, CORE, .NET MVC, Angular and Blockchain. Keen interest in addressing business problems using latest technologies and have been associated with Mobile Application Development Companies.

ImageLinkedIn: https://www.linkedin.com/in/vinodsatapara/

 

Was this article helpful?
YesNo
Shankar

Shankar is a tech blogger who occasionally enjoys penning historical fiction. With over a thousand articles written on tech, business, finance, marketing, mobile, social media, cloud storage, software, and general topics, he has been creating material for the past eight years.

Recent Posts

Essential Digital Tools For Entrepreneurs To Succeed In The Modern Marketplace

Building a robust online presence is no longer optional for entrepreneurs; it’s a necessity. Websites… Read More

3 days ago

The Benefits of Using Advanced Application Security Testing Tools

Advanced application security testing tools are key to the rapid pace of digital transformation. Applications… Read More

3 days ago

Top Challenges in Endpoint Management

Endpoint management is a superhero today. It caters to various requirements of an organization. These… Read More

3 days ago

The Best SEO Services in Dubai That Can Boost Your Online Presence

Today, it is impossible to conduct business by ignoring the online presence; therefore, it is… Read More

3 days ago

How Supply Chain Security Software Protects Against Cyberthreats

Simply put, supply chains are the cornerstone of modern businesses. They effectively connect organizations not… Read More

2 weeks ago

AI Agents vs. AI Chatbots: What’s the Difference?

AI is transforming customer service by making it quicker and more intelligent. Chatbots and AI… Read More

2 weeks ago