locked
Write to contacts on Xamarin.Forms RRS feed

  • Question

  • User295088 posted

    Hi, I'm trying to write contact information into their respective address books. I've seen examples on reading contacts (still haven't managed to get it to work, none of the examples compile, have to spend hours resolving bugs to get it to work!) but is there anything out there to write to contacts? From the AddressbookSample (https://github.com/softsan/AddressbookSample) , Xamarin.Contacts does not work. Xamarin.Mobile does not compile. Is there any way?

    Monday, February 27, 2017 3:51 PM

Answers

  • User259084 posted

    @DeviOS Firts of all you will have to create an interface and make use of dependency service to do this create an interface with a method. Nd implement this code in native Android and IOS project

    For Android:

         public void SaveContacts(string Name, string Number)
                {
    
                    var activity = Forms.Context as Activity;
                    var intent = new Intent(Intent.ActionInsert);
                    intent.SetType(ContactsContract.Contacts.ContentType);
                    intent.PutExtra(ContactsContract.Intents.Insert.Name, Name);
                    intent.PutExtra(ContactsContract.Intents.Insert.Phone, Number);
                    activity.StartActivity(intent);
                    Toast.MakeText(activity, "ContactSaved", ToastLength.Short).Show();
                }
    

    For IOS:

             public void SaveContacts(string Name, string Number)
                    {
                        var store = new CNContactStore();
                        var contact = new CNMutableContact();
                        var cellPhone = new CNLabeledValue<CNPhoneNumber>(CNLabelPhoneNumberKey.Mobile, new                   CNPhoneNumber(Number));
                        var phoneNumber = new[] { cellPhone };
                        contact.PhoneNumbers = phoneNumber;
                        contact.GivenName = Name;
                        var saveRequest = new CNSaveRequest();
                        saveRequest.AddContact(contact, store.DefaultContainerIdentifier);
                    }
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, March 1, 2017 5:04 AM

All replies

  • User76049 posted

    @JamesMontemagno has a pluggin, not sure it's supported but may be you started down the right path. I think it only reads the address book but might give you some ideas on how to get to the API's to write back.

    Ported from Xamarin.Mobile to a cross platform API.

    https://github.com/jamesmontemagno/ContactsPlugin https://www.nuget.org/packages/Xam.Plugin.Contacts

    Remember to enable read & write contacts in your Android manifest.

    Monday, February 27, 2017 5:40 PM
  • User259084 posted

    @DeviOS For which platform do you want it??

    Tuesday, February 28, 2017 9:22 AM
  • User295088 posted

    @NMackay Thank you for your suggestions. I installed Plugin.Contacts and was able to read the contacts. Still working out on how to write to the addressbook.. @VinayakGawas I want it for Android and iOS. Thank you.

    Tuesday, February 28, 2017 2:20 PM
  • User259084 posted

    @DeviOS Firts of all you will have to create an interface and make use of dependency service to do this create an interface with a method. Nd implement this code in native Android and IOS project

    For Android:

         public void SaveContacts(string Name, string Number)
                {
    
                    var activity = Forms.Context as Activity;
                    var intent = new Intent(Intent.ActionInsert);
                    intent.SetType(ContactsContract.Contacts.ContentType);
                    intent.PutExtra(ContactsContract.Intents.Insert.Name, Name);
                    intent.PutExtra(ContactsContract.Intents.Insert.Phone, Number);
                    activity.StartActivity(intent);
                    Toast.MakeText(activity, "ContactSaved", ToastLength.Short).Show();
                }
    

    For IOS:

             public void SaveContacts(string Name, string Number)
                    {
                        var store = new CNContactStore();
                        var contact = new CNMutableContact();
                        var cellPhone = new CNLabeledValue<CNPhoneNumber>(CNLabelPhoneNumberKey.Mobile, new                   CNPhoneNumber(Number));
                        var phoneNumber = new[] { cellPhone };
                        contact.PhoneNumbers = phoneNumber;
                        contact.GivenName = Name;
                        var saveRequest = new CNSaveRequest();
                        saveRequest.AddContact(contact, store.DefaultContainerIdentifier);
                    }
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, March 1, 2017 5:04 AM
  • User295088 posted

    Thank you @VinayakGawas! You saved my day(s). Its working like it should! Thank you very much again.

    Wednesday, March 1, 2017 2:56 PM
  • User301924 posted

    @VinayakGawas I tried a variant of this code to save a contact with multiple phone numbers and e-mail addresses, but my app crashes on iOS when trying to run this code. (Android works fine though, thanks for that!)

    Here's my method (phones and emails are both lists of strings containing the phone numbers and e-mail addresses):

            var store = new CNContactStore();
            var contact = new CNMutableContact();
            var phonesToSave = new List<CNLabeledValue<CNPhoneNumber>>();
            var mailsToSave = new List<CNLabeledValue<NSString>>();
            foreach(string number in phones)
            {
                phonesToSave.Add(new CNLabeledValue<CNPhoneNumber>("", new CNPhoneNumber(number)));
            }
            foreach(string mail in emails)
            {
                mailsToSave.Add(new CNLabeledValue<NSString>("", new NSString(mail)));
            }
            contact.PhoneNumbers = phonesToSave.ToArray();
            contact.GivenName = name;
            contact.EmailAddresses = mailsToSave.ToArray();
    
            var saveRequest = new CNSaveRequest();
            saveRequest.AddContact(contact, store.DefaultContainerIdentifier);
    
    Wednesday, May 3, 2017 3:08 PM
  • User295088 posted

    @TVH I'd suggest you step through the loops and see what's causing the crash. I'm not using a loop coz I save each contact once. But incase it helps, here's my complete iOS code.

    using System;
    using System.Threading;
    using AddressBook;
    using AddressBookUI;
    using Contacts;
    using ContactsUI;
    using DirList.iOS;
    using Foundation;
    using Plugin.Contacts;
    using Plugin.Contacts.Abstractions;
    using UIKit;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: Xamarin.Forms.Dependency(typeof(ContactAdder_iOS))]
    
    namespace DirList.iOS
    {
        public class ContactAdder_iOS : UIViewController, IAddContact
        {
            public void AddContactMethod(string name, string phone, string email)
            {
                System.Diagnostics.Debug.WriteLine("Contact service in iOS");
    
                //Check for contact permissions
                var authStatus = CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts);
                if (authStatus == CNAuthorizationStatus.Denied || authStatus == CNAuthorizationStatus.Restricted)
                { 
                    System.Diagnostics.Debug.WriteLine("Contacts Denied or Restricted");
                    throwAlertMethod("Contacts Permission Required", "This app requires permission to access your contacts. " +
                                     "Please go to Settings>AppName and enable access.");
                    return;
                }
    
                //if user adds contact for 1st time
                if (authStatus == CNAuthorizationStatus.NotDetermined)
                {
                    System.Diagnostics.Debug.WriteLine("Contact permission not determined");
                    var store = new CNContactStore();
                    store.RequestAccess(CNEntityType.Contacts, (granted, error) =>
                    {
                        if (!granted)
                        {
                            throwAlertMethod("Contacts Permission Required", "This app requires permission to access your contacts, " +
                                             "please go to Settings>AppName and re-enable permissions.");
                            return;
                        }
                        else
                        {
                            saveContactToStoreMethod(name, phone, email);
                        }
                    });
                }
                else
                {
                    saveContactToStoreMethod(name, phone, email);
                }
            }
    
            void saveContactToStoreMethod(string name, string phone, string email)
            {
                var store = new CNContactStore();
                var contact = new CNMutableContact();
                var cellPhone = new CNLabeledValue<CNPhoneNumber>(new NSString("work"), new CNPhoneNumber(phone));
                var workEmail = new CNLabeledValue<NSString>(new NSString("work"), new NSString(email));
                var emailAdd = new[] { workEmail };
                var phoneNumber = new[] { cellPhone };
                contact.PhoneNumbers = phoneNumber;
                contact.EmailAddresses = emailAdd;
                contact.OrganizationName = "XXXX";
                contact.GivenName = name;
                var saveRequest = new CNSaveRequest();
                saveRequest.AddContact(contact, store.DefaultContainerIdentifier);
    
                NSError error;
                if (store.ExecuteSaveRequest(saveRequest, out error))
                {
                    Console.WriteLine("New contact saved");
                    throwToastMethod("Contact Saved");
                }
                else
                {
                    Console.WriteLine("save error {0}", error);
                    throwToastMethod("Error saving contact");
                }
            }
    
            void throwAlertMethod(string heading, string Body)
            { 
                var alertController = UIAlertController.Create(heading, Body, UIAlertControllerStyle.Alert);
                alertController.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
    
                UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alertController, true, null);
            }
    
            void throwToastMethod(string message)
            { 
                var toast = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
                UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(toast, false, null);
    
                //Add Delay to dismiss the alert view without any user interaction
                new Timer((state) => InvokeOnMainThread(() => toast.DismissViewController(true, null)),
                                           null,
                                           600,
                                           Timeout.Infinite);
    
            }
        }
    }
    
    Wednesday, May 3, 2017 3:22 PM
  • User301924 posted

    Thanks @DeviOS. I think my app crashed previously because it didn't check permissions, so I added your code to do so. However, now the method still isn't working. Sometimes it goes through the method, but the contact isn't saved, sometimes the app crashes when asking for permission.

    For reference, here's my full class:

    public class UserContactService : IUserContactService
    {
        public async Task<bool> AddContact(string name, List<string> phones, List<string> emails)
        {
            bool hasPermission = CheckPermission();
    
            if (hasPermission == true)
            {
                var store = new CNContactStore();
                var contact = new CNMutableContact();
                var phonesToSave = new List<CNLabeledValue<CNPhoneNumber>>();
                var mailsToSave = new List<CNLabeledValue<NSString>>();
                foreach (string number in phones)
                {
                    phonesToSave.Add(new CNLabeledValue<CNPhoneNumber>("", new CNPhoneNumber(number)));
                }
                foreach (string mail in emails)
                {
                    mailsToSave.Add(new CNLabeledValue<NSString>("", new NSString(mail)));
                }
                contact.PhoneNumbers = phonesToSave.ToArray();
                contact.GivenName = name;
                contact.EmailAddresses = mailsToSave.ToArray();
    
                var saveRequest = new CNSaveRequest();
                saveRequest.AddContact(contact, store.DefaultContainerIdentifier);
    
                return true;
            }
            return false;
        }
    
        private bool CheckPermission()
        {
            var authStatus = CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts);
            if (authStatus == CNAuthorizationStatus.Denied || authStatus == CNAuthorizationStatus.Restricted)
            {
                System.Diagnostics.Debug.WriteLine("Contacts Denied or Restricted");
                throwAlertMethod("Contacts Permission Required", "This app requires permission to access your contacts. " +
                                                                 "Please go to Settings>FollowItUp and enable access.");
                return false;
            }
    
            //if user adds contact for 1st time
            bool check = false;
            if (authStatus == CNAuthorizationStatus.NotDetermined)
            {
                var store = new CNContactStore();
                store.RequestAccess(CNEntityType.Contacts, (granted, error) =>
                {
                    if (!granted)
                    {
                        throwAlertMethod("Contacts Permission Required", "This app requires permission to access your contacts, " +
                                                                         "please go to Settings>FollowItUp and re-enable permissions.");
                        //check = false;
                        return;
                    }
                    else
                    {
                        check = true;
                    }
                });
            }
            else
            {
                check = true;
            }
            return check;
        }
    
        void throwAlertMethod(string heading, string Body)
        {
            var alertController = UIAlertController.Create(heading, Body, UIAlertControllerStyle.Alert);
            alertController.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
    
            UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alertController, true, null);
        }
    
    Thursday, May 4, 2017 3:01 PM
  • User295088 posted

    Hey @TVH , It was working fine for me without crashing, until one day. It started throwing a SIGABRT error when asking for permission. Same issue even on Debug and Release builds. However, it doesn't crash using a release build on a Device, only crashes in the simulator. Funny.

    Monday, June 5, 2017 4:45 PM
  • User339155 posted

    hi... now i am creating simple application in xamrin forms i have one doubt for me....please help me

    my task is , read contact details from phone to my app i have completed Read contact name and id but contact number cant able

    Thursday, August 10, 2017 11:01 AM
  • User159250 posted

    Hi, I solved the SIGABRT issue, by adding "Privacy - Contacts usage description" entry in info.plist. now the code works till saveRequest.AddContact. I've no error, but the app do nothing, any contact or gui to add it. On Android it works fine. Any help?

    Monday, March 5, 2018 11:04 AM
  • User159250 posted

    Hi, I solved my issue, by adding this code after saveRequest.AddContact

    NSError error; if (store.ExecuteSaveRequest(saveRequest, out error)) { Console.WriteLine("New contact saved"); } else { Console.WriteLine("Save error: {0}", error); }

    Monday, March 5, 2018 11:14 AM
  • User153793 posted

    @VinayakGawas

    Do you have an example (for android and iOS) how to read a contact with the same approach?

    Regards rubenc

    Monday, April 2, 2018 12:00 AM
  • User374708 posted

    Hello @DeviOS and @VinayakGawas

    I have to implement add contact in Address book. so please help me which plugin I have to implement and how. As I am new in xamarin forms.

    Thanks you

    Monday, October 15, 2018 5:35 AM
  • User377758 posted

    @Gandhi_123 Could you share the basic demo of adding contact in Address book?

    Monday, October 15, 2018 6:07 AM
  • User374708 posted

    Hello @Tracy320

    As of now I have implement read contact code which is given below:

    private async void Button_Clicked(object sender, EventArgs e) { switch (Device.RuntimePlatform) {

                case Device.Android:
                    var ContactList = await DependencyService.Get<IContacts>().GetDeviceContactsAsync();
                    listContact.ItemsSource = ContactList;
                    break;
                default:
                    break;
            }
        }
    

    But now I want to implement Write Contact code. and I don't understand how to start. Please help me.

    Thank You

    Monday, October 15, 2018 7:13 AM
  • User374708 posted

    Hello @DeviOS , @VinayakGawas

    Thanks for the best solution but I want to know that how to come back in our xamarin forms app after saving contact.

    Monday, October 15, 2018 10:07 AM
  • User374708 posted

    Hello @VinayakGawas , @DeviOS , @TVH

    This is the perfect solution for save contact in phone book. I have applied in android and its work perfectly but when i have applied in ios the contcat is not saved . So please help me for come out with this problem.

    Thanks in advance!!!!!!

    Wednesday, January 9, 2019 7:21 AM
  • User374708 posted

    @Gandhi_123 said: Hello @VinayakGawas , @DeviOS , @TVH

    This is the perfect solution for save contact in phone book. I have applied in android and its work perfectly but when i have applied in ios the contcat is not saved . So please help me for come out with this problem.

    Thanks in advance!!!!!!

    Wednesday, January 9, 2019 9:26 AM
  • User387875 posted

    @VinayakGawas said: @DeviOS Firts of all you will have to create an interface and make use of dependency service to do this create an interface with a method. Nd implement this code in native Android and IOS project

    For Android:

         public void SaveContacts(string Name, string Number)
                {
    
                    var activity = Forms.Context as Activity;
                    var intent = new Intent(Intent.ActionInsert);
                    intent.SetType(ContactsContract.Contacts.ContentType);
                    intent.PutExtra(ContactsContract.Intents.Insert.Name, Name);
                    intent.PutExtra(ContactsContract.Intents.Insert.Phone, Number);
                    activity.StartActivity(intent);
                    Toast.MakeText(activity, "ContactSaved", ToastLength.Short).Show();
                }
    

    For IOS:

             public void SaveContacts(string Name, string Number)
                    {
                        var store = new CNContactStore();
                        var contact = new CNMutableContact();
                        var cellPhone = new CNLabeledValue<CNPhoneNumber>(CNLabelPhoneNumberKey.Mobile, new                 CNPhoneNumber(Number));
                        var phoneNumber = new[] { cellPhone };
                        contact.PhoneNumbers = phoneNumber;
                        contact.GivenName = Name;
                        var saveRequest = new CNSaveRequest();
                        saveRequest.AddContact(contact, store.DefaultContainerIdentifier);
                    }
    

    I m try to do this play but it don´t identify Forms.Context, Intent and ContactsContract. Has assembly or using for add? Thanks

    Wednesday, November 27, 2019 1:16 PM
  • User398583 posted

    @VinayakGawas , @NMackay Hello my friends, I come to write here on the article because I am looking for a solution to my problem. My problem is that I want to save a contact with the save what method, but first I would like to check if the contact I want to save exists. If anyone has a great idea or link solution to adapt. I think it will make me happy and help me tremendously. Thank you

    Monday, January 4, 2021 12:28 PM