Is there a standard way of opening the native Contacts app for all XF-supported platforms?

JohnHardmanJohnHardman GBUniversity mod

Given a contact name or a combination of first name/last name/company name, I want to launch the native Contacts app on the device and have it open either the one matching contact, or if there are multiple matches either open the first match or list the matches (if that is supported). I don't really want to retrieve contacts information and show it in pages implemented in my app, even though using the Contacts app means users navigating away from my app.

Is there any standard way of doing this, such as using a call to Device.OpenUri with an appropriately constructed Uri ?

Best Answer

Answers

  • SgXam15SgXam15 INMember ✭✭

    Hi @JohnHardman were you able to implement the same?I am stuck with similar problem.I also want to know how to develop a UI using XF that can be populated from a dictionary or equivalent.Like I have many entries with images,label etc.I want to create an UI that would be rendered using all the elements.For ex- in stack layout I have to specify the items again and again.What when I wanted to dynamically generate the same without the need for specifying each and every similar type of element.Kindly help.

    P.S - Listitem cant be used as modal view is required but list view occupies the entire screen.

  • JohnHardmanJohnHardman GBUniversity mod
    edited July 2016

    @SgXam15 -

    Actually, implementing the equivalent on UWP to get contacts from the People app is simple enough. Whilst not complete, nor production-ised, the following is a quick proof-of-concept to show that it can be done:

         public async Task<IList<Plugin.Contacts.Abstractions.Contact>> GetAllContacts()
        {
            List<Plugin.Contacts.Abstractions.Contact> contacts = new List<Plugin.Contacts.Abstractions.Contact>();
    
            ContactStore contactStore 
                = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AllContactsReadOnly);
            IReadOnlyList<Windows.ApplicationModel.Contacts.Contact> contactList 
                = await contactStore.FindContactsAsync();
    
            foreach (Windows.ApplicationModel.Contacts.Contact contact in contactList)
            {
                contacts.Add(new Plugin.Contacts.Abstractions.Contact(contact.Id, false)
                    {
                        DisplayName = contact.DisplayName,
                        FirstName = contact.FirstName,
                        MiddleName = contact.MiddleName,
                        LastName = contact.LastName,
                        Nickname = contact.Nickname,
                        Prefix = contact.HonorificNamePrefix,
                        Suffix = contact.HonorificNameSuffix
                    });
            }
    
            return contacts;
        }
    
  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - It appears that Windows 8.1 doesn't give the option of enumerating the address book. Instead, the app needs to provide what are effectively search criteria, which are used to open a Contact Card. The system tries to find the correct contact based on details provided, but if it doesn't find a match, it will just show the details that the app provides. More proof-of-concept code below, based on video at http://channel9.msdn.com/Events/Build/2013/3-007

        public void OpenContactCardForUser(string searchCriteria, VisualElement element)
        {
            Contact contact = new Windows.ApplicationModel.Contacts.Contact();
    
            Windows.ApplicationModel.Contacts.ContactPhone phone = new Windows.ApplicationModel.Contacts.ContactPhone();
            phone.Number = "{phone number here}";
            contact.Phones.Add(phone);
    
            contact.FirstName = "John";
            contact.LastName = "Hardman";
    
            ContactEmail email = new ContactEmail();
            email.Address = "{email here}";
            contact.Emails.Add(email);
    
            Rectangle boundingRect = element.Bounds;
            Rect selectionRect = new Rect(
                boundingRect.Left,
                boundingRect.Top,
                boundingRect.Width * 2/3,
                boundingRect.Height * 2/3);
    
            ContactManager.ShowContactCard(contact, selectionRect);
        }
    
  • SgXam15SgXam15 INMember ✭✭

    Hi @JohnHardman .Thanks for the help and your time.It helped me to widen my knowledge spectrum as me being a newbie to Xamarin. But for my app, I am targeting android,IOS wherein this doesn't seem to work.Can you please elucidate on the same?And how should I go about populating the UI of Contacts Page from "n" entries in the contact list of the phone.The reason being,so far what I have learnt is,one needs to provide layout and items fitting in.So say in Stack layout I would have to provide items that I want in the UI.But how should I preprogram this,as in how to get the layout dynamically populated or created..I am absolutely flummoxed with this problem.Can you help?

  • JohnHardmanJohnHardman GBUniversity mod
    edited July 2016

    @SgXam15 - If you are just targeting Android and iOS, then I would suggest using https://www.nuget.org/packages/Xam.Plugin.Contacts , which does work.

    As for how to learn to create a UI using Xamarin.Forms that can show such data, there are various options. Whilst not cheap (but it is great value), university.xamarin.com is a great learning resource. They do a free trial, so you can make a start even if you don't end up paying the subscription. I think the free trial is 30 days now, so you can actually pack a lot of courses in during that time.

    Alternatively, there are various resources available. The following three are all on Amazon, but if you Google them, you should be able to find free electronic versions of the first two:

    "Xamarin.Forms Kickstarter 2.0: Compilable Code Examples for Solving Typical Cross-platform Tasks"
    "Creating Mobile Apps with Xamarin.Forms Preview Edition 2 (Developer Reference)"
    "Xamarin Mobile Application Development: Cross-Platform C# and Xamarin.Forms Fundamentals"

    To integrate the Contacts data, you will want to look at ListView, DependencyService, MVVM, Tasks and await.

    Whilst not everything you need, here are some code snippets to help. I threw these together as a proof-of-concept yesterday, so they won't be perfect, but they may help. Note that I added more to my own version of this to cope with UWP and the different behavior on Windows 8.1 RT. I haven't included those bits here, as you only mentioned targeting iOS and Android:

    (1) A base class with functionality common to Android and iOS. TBH - I'm not 100% sure if this is ok for the contacts plugin (@JamesMontemagno - can you confirm please?), but I haven't seen it not work.

    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    using Plugin.Contacts;
    
    namespace CommonInfrastructure
    {
        public interface IContactsService
        {
            Task<IList<Contact>> GetAllContacts();
        }
    
        public class BaseContactsService
        {
            public async Task<IList<Plugin.Contacts.Abstractions.Contact>> GetAllContacts()
            {
                List<Plugin.Contacts.Abstractions.Contact> contacts = null;
    
                if (await CrossContacts.Current.RequestPermission())
                {
                    CrossContacts.Current.PreferContactAggregation = false;
    
                    await Task.Run(() =>
                    {
                        if (CrossContacts.Current.Contacts == null)
                            return;
    
                        contacts = CrossContacts.Current.Contacts.ToList();
    
                        if (contacts != null)
                            contacts = contacts.OrderBy(c => c.LastName).ToList();
                    });
                }
    
                return contacts;
            }
        }
    }
    

    (2) A dependency service implementation in your Android project:

    namespace MyApp.Droid
    {
        public class ContactsService : BaseContactsService, IContactsService
        {
        }
    }
    

    (3) Registering the dependency service in your Android project:

    DependencyService.Register<MyApp.Droid.ContactsService>();
    

    (4) A dependency service implementation in your iOS project:

    namespace MyApp.iOS
    {
        public class ContactsService : BaseContactsService, IContactsService
        {
        }
    }
    

    (5) Registering the dependency service implementation in your iOS project:

    DependencyService.Register<MyApp.iOS.ContactsService>();
    

    (6) Making use of the dependency service to retrieve all of the available contacts:

        IContactsService contactsService = DependencyService.Get<IContactsService>();
        if (contactsService != null)
        {
            IList<Contact> contacts = await contactsService.GetAllContacts();
            if (contacts != null)
            {
                // got the contacts here, so do something with them...
            }
        }
    
  • SgXam15SgXam15 INMember ✭✭

    Hi @JohnHardman .Thanks a lot for the help.Kindly accept my gratitude for the same.The code structure is quite byzantine though for a novice like me.But I think these could be used as stepping stones to unfurl the magic of xamarin and learn more.Thanks for laying a helping hand to get me hone my skill set in xamarin.

    Yes,I am only concentrating, as of now, for android and IOS.One thing I floundered upon was the courses offered upon by university.xamarin.com,as in you mean to say the payment would be required for the online classes like udacity,udemy etc or to access the material of creating such UI's and learning more about Xamarin from such platform?Also I would love to get some resources or websites that guide through step by step over Xamarin.Forms,i.e,Simple to intriguing UI development,backend code etc..or some crash course that could help me learn fast.Do you have any references for the same?

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - You can start a trial for Xamarin University at https://www.xamarin.com/university . I've just taken a look - you don't get access to all courses whilst on the free-trial. This is what it says "Start your 30-day trial to access our Self-Guided Learning, Lightning Lectures, Guest Lectures, and two introductory courses which count towards your certification". Give that a try -

    Start with these two, which can be done as self-guided or with a tutor:
    Introduction to Cross-Platform Mobile Development [XAM110]
    Intro to Xamarin.Forms [XAM120]

    For the other references, Google the following. As mentioned previously, the first two are available online at no charge, but all three can be obtained through Amazon (at a charge):
    "Xamarin.Forms Kickstarter 2.0: Compilable Code Examples for Solving Typical Cross-platform Tasks"
    "Creating Mobile Apps with Xamarin.Forms Preview Edition 2 (Developer Reference)"
    "Xamarin Mobile Application Development: Cross-Platform C# and Xamarin.Forms Fundamentals"

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman Thanx for the guidance.I shall abide by the same.Meanwhile, regarding the UI for the contacts page,I tried using list view as a modal view in xamarin.forms. The effect is not the desired one.I want the modal view or the contacts page to occupy not the whole screen or window and have a transparent background.In using list view and trying other approaches related to the same I witnessed the page size cant be adjusted this way.Basically,resizing list view page is not possible(atlas this is what I could infer from my confined knowledge and tryouts).I think stack layout need to be used for the same but then how can I add children in the layout at the very onset without knowing other details.Plus,I want to have an image with a name(like whatsapp) UI in the contacts page.Am I missing anything or going wrong anywhere?

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - If you will be displaying more than one page of contact information, stick with a ListView rather than a StackLayout. It will be more responsive for the user.

    Regarding not covering the whole screen, you will probably want to use a plugin for creating dialogs to do that. I know there is one, but I haven't used it. Have a search on the forum regarding dialogs for Xamarin.Forms . There will be plenty of mentions of it.

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman Thanks for a lot for the replies.I am sorry to bother with my puerile queries.But thanks for playing the role of a mentor to guide me in the right direction.

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman another thing I would like to mention that I forgot to add was in Xmarin.forms there are no dialog box unlike Android ,where there is AlertDialog class.So to use list view likewise to populate Contact list (modal view)I guess I have to use stack layout.If you think otherwise please let me know.

  • JohnHardmanJohnHardman GBUniversity mod

    There are various options.

    If you simply want to display a single string per contact (e.g. the DisplayName), and pick one, then you could use a Picker or DisplayActionSheet.

    If you will have more than one page of contacts, or want to display more information for each contact, you will normally want to use a ListView.

    I wouldn't use a StackLayout unless you only have a small number of contacts to display, as performance becomes an issue with larger volumes of data, particularly on Android.

    For DisplayActionSheet, see https://developer.xamarin.com/guides/xamarin-forms/user-interface/navigation/pop-ups/

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman Ok.I know.But what to do when there is a requirement of creating a view of contacts where each item possess a circular image view of the contact and its name aligned horizontally to the left of the image and this entire contacts page would be modal view with transparent background and layout of this contacts page not occupying the entire screen but lesser pixels along height and width of the screen so that background base page is visible (blurred though)?

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - I'd still use a ListView, using ViewCell to allow you to create the appearance that you want for each contact. For something similar, take a look at https://www.syntaxismyui.com/xamarin-forms-listview-custom-viewcell-recipe/

    For the modal view with transparent background etc., Google dialogs for Xamarin.Forms (there is a component/plugin for creating them, but I don't use it, so cannot remember what it is called).

  • JohnHardmanJohnHardman GBUniversity mod

    I've just implemented integration with contacts on UWP, by integrating with the People app. If anybody ever needs to do this, be aware that there are typo's in the documentation for the People app usage, most annoyingly in the samples of URIs for when using URIs instead of the class API.

    Also, whether it's a bug in my code (I don't think so), a bug in Microsoft's code, or just a limitation that I haven't seen documented, whilst on Windows 10 desktop either the API or URI method works, I found that on a Windows 10 phone, only the URI method works.

  • SgXam15SgXam15 INMember ✭✭

    Hi @JohnHardman in reference to your suggestion I tried using the Plugin.Contacts.But got stuck.Would you be able to guide me for the same?I am unable to retrieve the contacts of my phone.

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - If you step through the code above, how far for you get? Is it that it doesn't pass the permissions test?

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman I am unable to get the code running.I would like to brief you regarding my implementation,just in case I am missing any link for the code to work aptly.

    I have created two separate classes,one the common class for both IOS,android while the second being in IOS.The code for the same is as follows:

    ContactsService.cs (IOS):

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    using System.Linq;
    using Plugin.Contacts;
    using UIKit;
    using MyProj.iOS;
    using Xamarin.Forms.Platform.iOS;

    [assembly: Xamarin.Forms.Dependency(typeof(MyProj.iOS.ContactService))]

    namespace MyProj.iOS
    {

    public class ContactService : IContactsService
        {
        private static IList<Plugin.Contacts.Abstractions.Contact> _contacts;
    
        public ContactService()
            {
            }
    
            public async Task<IList<Plugin.Contacts.Abstractions.Contact>> GetAllContacts()
            {
                if (_contacts != null) return _contacts;
    
                var contacts = new List<Plugin.Contacts.Abstractions.Contact>();
    
            if (await CrossContacts.Current.RequestPermission())
    
                CrossContacts.Current.PreferContactAggregation = false;
    
            await Task.Run(() =>
            {
                if (CrossContacts.Current.Contacts == null)
                    return;
    
                contacts = CrossContacts.Current.Contacts.ToList();
    
                if (contacts != null)
                    contacts = contacts.OrderBy(c => c.LastName).ToList();
            });
    
                return contacts;
            }
        }
    }
    

    Baseclass in XF:

    ContactsViewModel.cs

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    using Plugin.Contacts;
    using System.Linq;

    namespace MyProj
    {

    public interface IContactsService
    {
        Task<IList<Plugin.Contacts.Abstractions.Contact>> GetAllContacts();
    }
    
    public class ContactsViewModel
    {
        private readonly IContactsService _contactService;
        public IList<Plugin.Contacts.Abstractions.Contact> Contacts { get; set; }
    
        public ContactsViewModel()
        {
            _contactService = DependencyService.Get<IContactsService>();
        }
    
        public void LoadContacts()
        {
            Contacts = _contactService.GetAllContacts().Result;
        }
    
        }
    

    }

    I am unable to fathom how to go about the implementation ,if the code is correct, and how should I use this to populate my Listview popup page that I have created in XF.

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - Have you stepped through the code in a debugger? If so, how far does it get? Does GetAllContacts get called?

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman I was trying to implement this for android and IOS.Nothing is getting displayed.What should I do for android?The code structure would remain the same as IOS right?Why am I not getting any error or any output?I must be missing something.Is my code right in accordance to you?

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 - I need more info in order to advise. Have you stepped through the code in a debugger? If so, how far does it get? Does GetAllContacts get called?

  • SgXam15SgXam15 INMember ✭✭

    @JohnHardman No its not getting called.I am trying to code in android to check if it works out there using the same base class.Any pointers for android implementation?Also, by any means have you used picker class for adding items of type "view" rather than strings?I haven't been able to find any implementation where a picker accepts a view rather than just strings.I gotta use this in my contacts screen too.Any comments?

  • JohnHardmanJohnHardman GBUniversity mod

    @SgXam15 -

    (a) Is your LoadContacts method being called?
    (b) Are you getting any warnings when you compile your code (warning level 4 recommended), particularly any relating to async?
    (c) Are any exceptions thrown?
    (d) Have you registered the dependency service?

    Re. Android, see (2) and (3) in my earlier post.

Sign In or Register to comment.