Quickstart: Handling contact actions (XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Through the Windows.ApplicationModel.Activation namespace, you can provide data to an app when it's activated for several contact actions (Windows.ApplicationModel.Contacts.ContactLaunchActionVerbs). Here, we'll show you how to handle app activation when a user attempts to make a phone call to a contact, send a message to a contact, or get the map to a contact's address. These app activation actions can occur from a contact card retrieved from the Windows Search experience or from within an app. A contact card can be displayed from within an app with the ContactManager.ShowContactCard and ContactManager.ShowDelayLoadedContactCard methods. Handling app activation for contact actions is supported starting with Windows 8.1.

Here we reference the Handling Contact Actions sample. This sample demonstrates how to handle app activation for contact actions through the API of the Windows.ApplicationModel.Activation namespace from within Windows Store apps.

The sample provides three scenarios:

  1. Handling an activation to make a call (ContactLaunchActionVerbs.Call)
  2. Handling an activation to send a message (ContactLaunchActionVerbs.Message)
  3. Handling an activation to map an address (ContactLaunchActionVerbs.Map)

Prerequisites

  • We recommend that you be familiar with Microsoft Visual Studio and its associated templates.
  • We recommend that you be familiar with C# development.

Include manifest registrations for each action that the app needs to support

In the AppxManifest.xml or Package.appxmanifest file, update the Package element to accept the Windows 8.1 manifest schema and include the manifest registrations for each action that the app needs to support. These registrations allow the app to be launched when any of the contact actions or protocol schemes occur.

<Package xmlns="https://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="https://schemas.microsoft.com/appx/2013/manifest">
.
.
      <Extensions>
        <Extension Category="windows.protocol">
          <Protocol Name="tel"/>
        </Extension>        
        <m2:Extension Category="windows.contact">
          <m2:Contact>
            <m2:ContactLaunchActions>
              <m2:LaunchAction Verb="call">
                <m2:ServiceId>telephone</m2:ServiceId>
              </m2:LaunchAction>
              <m2:LaunchAction Verb="message">
                <m2:ServiceId>skype.com</m2:ServiceId>
              </m2:LaunchAction>            
              <m2:LaunchAction Verb="map"/>
            </m2:ContactLaunchActions>
          </m2:Contact>
        </m2:Extension>
      </Extensions>      

Determine the scenario to act on

Create a IContactActivatedEventArgs object and assign it to a variable. The scenario to act on is determined by the contact action that is performed. For example, if the user clicks Call on a contact's phone number, the IContactActivatedEventArgs.Verb is ContactLaunchActionVerbs.Call, and the scenario to act on is CallScenario.

Because we recommend that apps that implement the Windows.Contact.call action also implement support for the tel: protocol, you need to also create a ProtocolActivatedEventArgs object and assign it to a variable.

        private IContactActivatedEventArgs _contactEventArgs = null;
        public IContactActivatedEventArgs ContactEvent
        {
            get { return _contactEventArgs; }
            set { _contactEventArgs = value; }
        }


        private ProtocolActivatedEventArgs _protocolEventArgs = null;
        public ProtocolActivatedEventArgs ProtocolEvent
        {
            get { return _protocolEventArgs; }
            set { _protocolEventArgs = value; }
        }

       public void NavigateToContactEventPage()
        {
            if (this.ContactEvent != null)
            {
                string errorNotification = null;
                if (this.ContactEvent.Verb == ContactLaunchActionVerbs.Call)
                {
                    Scenarios.SelectedIndex = 0;
                }
                else if (this.ContactEvent.Verb == ContactLaunchActionVerbs.Message)
                {
                    Scenarios.SelectedIndex = 1;
                }
                else if (this.ContactEvent.Verb == ContactLaunchActionVerbs.Map)
                {
                    Scenarios.SelectedIndex = 2;
                }
                else
                {
                    Scenarios.SelectedIndex = 0;
                    errorNotification = "This app can't handle the contact action verb it was activated for.";
                }

                Scenarios.ScrollIntoView(Scenarios.SelectedItem);
                LoadScenario(scenarios[Scenarios.SelectedIndex].ClassType);
                if (!String.IsNullOrEmpty(errorNotification))
                {
                    this.NotifyUser(errorNotification, NotifyType.ErrorMessage);
                }
            }
        }

Provide data to the app when it's activated with a call

Determine whether we're getting a contact call event or a tel: protocol call event.

The data passed in here for the contact call event (IContactActivatedEventArgs) are ServiceId and ServiceUserId. The sample uses the phone number of the selected contact and prints, for example, "Call activation was received. The phone number to call is (555) 555-0100."

The data passed in here for the tel: protocol call event (ProtocolActivatedEventArgs) are URI Scheme and AbsolutePath. The sample uses the phone number of the selected contact and prints, for example, "Tel: activation was received. The phone number to call is (555) 555-0100."

    /// <summary>
    /// A page for 'Handling an activation to make a call' scenario that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class CallScenario
    {
        // A pointer back to the main page.  This is needed if you want to call methods in MainPage such
        // as NotifyUser()
        MainPage rootPage = MainPage.Current;

        public CallScenario()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (rootPage.ContactEvent != null)
            {
                IContactCallActivatedEventArgs callArgs = rootPage.ContactEvent as IContactCallActivatedEventArgs;
                if (callArgs != null)
                {
                    if (callArgs.ServiceId == "telephone")
                    {
                        rootPage.NotifyUser(
                            String.Format("Call activation was received. The phone number to call is {0}.", callArgs.ServiceUserId),
                            NotifyType.StatusMessage);
                    }
                    else
                    {
                        rootPage.NotifyUser(
                           String.Format("This app doesn't support calling by using the {0} service.", callArgs.ServiceId),
                           NotifyType.ErrorMessage);
                    }
                }
            }
            else if (rootPage.ProtocolEvent != null)
            {
                Uri protocolUri = rootPage.ProtocolEvent.Uri;
                if (protocolUri.Scheme == "tel")
                {
                    rootPage.NotifyUser(
                        String.Format("Tel: activation was received. The phone number to call is {0}.", protocolUri.AbsolutePath),
                        NotifyType.StatusMessage);
                }
                else
                {
                    rootPage.NotifyUser(
                        String.Format("This app doesn't support the {0} protocol.", protocolUri.Scheme),
                        NotifyType.ErrorMessage);
                }
            }
        }
    }

Provide data to the app when it's activated with a message send

The contact event is cast as a ContactMessageActivatedEventArgs object. The data passed in here for the contact send-message event (ContactLaunchActionVerbs.Message) are ServiceId and ServiceUserId. The sample uses the contact’s user id for the particular service and prints, for example, "Send message activation was received. The service to use is contoso.com. The user ID to message is userid10".

    /// <summary>
    /// A page for 'Handling an activation to send a message' scenario that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class SendMessageScenario
    {
        // A pointer back to the main page.  This is needed if you want to call methods in MainPage such
        // as NotifyUser()
        MainPage rootPage = MainPage.Current;

        public SendMessageScenario()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (rootPage.ContactEvent != null)
            {
                ContactMessageActivatedEventArgs messageArgs = rootPage.ContactEvent as ContactMessageActivatedEventArgs;
                if (messageArgs != null)
                {
                    rootPage.NotifyUser(
                        String.Format("Send message activation was received. The service to use is {0}. The user ID to message is {1}.", messageArgs.ServiceId, messageArgs.ServiceUserId),
                        NotifyType.StatusMessage);
                }
            }
        }
    }

Provide data to the app when it's activated with a map request

The contact event is cast as a ContactMapActivatedEventArgs object. The data passed in for the contact map-request event (ContactLaunchActionVerbs.Map) is ContactAddress. The sample uses the contact's street address and prints, for example, "Map address activation was received. The street address to map is One Microsoft Way".

    /// <summary>
    /// A page for 'Handling an activation to map an address' scenario that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MapAddressScenario
    {
        // A pointer back to the main page.  This is needed if you want to call methods in MainPage such
        // as NotifyUser()
        MainPage rootPage = MainPage.Current;

        public MapAddressScenario()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (rootPage.ContactEvent != null)
            {
                ContactMapActivatedEventArgs mapArgs = rootPage.ContactEvent as ContactMapActivatedEventArgs;
                if (mapArgs != null)
                {
                    Windows.ApplicationModel.Contacts.ContactAddress address = mapArgs.Address;
                    rootPage.NotifyUser(
                        String.Format("Map address activation was received. The street address to map is {0}.",
                            String.IsNullOrEmpty(address.StreetAddress) ? "unspecified" : address.StreetAddress),
                        NotifyType.StatusMessage);
                }
            }
        }
    }

Summary and next steps

Now you have a basic understanding of how to handle app activation for contact actions. Download the Handling Contact Actions sample from the code gallery to see the complete sample of how to handle app activation for contact actions.

Handling Contact Actions sample