Quickstart: Handling contact actions (HTML)

Through the Windows.UI.WebUI and Windows.ApplicationModel.Activation namespaces, 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.UI.WebUI 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 JavaScript 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

The app is launched when either the contact or protocol Windows.ApplicationModel.Activation.ActivationKind activation type occurs.

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 event action is ContactLaunchActionVerbs.call, and the scenario to act on is S1-Call.

Because we recommend that apps that implement the Windows.Contact.call action also implement support for the tel: protocol, you need to also act on the S1-Call scenario when the protocol Windows.ApplicationModel.Activation.ActivationKind is detected.

    function activated(eventObject) {
        var url = null;
        var arg = null;

        if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.contact) {
            // If activated for a contact, launch the appropriate action handling scenario.
            arg = eventObject.detail;
            if (eventObject.detail.verb === Windows.ApplicationModel.Contacts.ContactLaunchActionVerbs.call) {
                url = scenarios[0].url;
            } else if (eventObject.detail.verb === Windows.ApplicationModel.Contacts.ContactLaunchActionVerbs.message) {
                url = scenarios[1].url;
            } else if (eventObject.detail.verb === Windows.ApplicationModel.Contacts.ContactLaunchActionVerbs.map) {
                url = scenarios[2].url;
            } else {
                WinJS.log && WinJS.log("This app can't handle the contact action verb it was activated for.", "sample", "error");
                return;
            }
        } else if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.protocol) {
            // If activated for a protocol, launch the call scenario
            arg = eventObject.detail;
            url = scenarios[0].url;
        } else if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
            // Otherise, navigate to either the first scenario or to the last running scenario
            // before suspension or termination.
            url = WinJS.Application.sessionState.lastUrl || scenarios[0].url;
        }

        if (url !== null) {
            // Use setPromise to indicate to the system that the splash screen must not be torn down
            // until after processAll and navigate complete asynchronously.
            eventObject.setPromise(WinJS.UI.processAll().then(function () {
                return WinJS.Navigation.navigate(url, arg);
            }));
        }
    }

    WinJS.Navigation.addEventListener("navigated", function (eventObject) {
        var url = eventObject.detail.location;
        var host = document.getElementById("contentHost");
        // Call unload method on current scenario, if there is one
        host.winControl && host.winControl.unload && host.winControl.unload();
        WinJS.Utilities.empty(host);
        eventObject.detail.setPromise(WinJS.UI.Pages.render(url, host, eventObject.detail.state).then(function () {
            WinJS.Application.sessionState.lastUrl = url;
        }));
    });

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 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 are URI schemeName and path. 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."

(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/S1-Call.html", {
        processed: function (element, callArgs) {
            // callArgs is the parameter passed to navigation in the activated event handler.
            if (callArgs) {
                if (callArgs.serviceId) {
                    if (callArgs.serviceId === "telephone") {
                        WinJS.log && WinJS.log("Call activation was received. The phone number to call is " + callArgs.serviceUserId + ".", "sample", "status");
                    } else {
                        WinJS.log && WinJS.log("This app doesn't support calling by using the " + callArgs.serviceId + " service.", "sample", "error");
                    }
                } else if (callArgs.uri) {
                    if (callArgs.uri.schemeName === "tel") {
                        WinJS.log && WinJS.log("Tel: activation was received. The phone number to call is " + callArgs.uri.path + ".", "sample", "status");
                    } else {
                        WinJS.log && WinJS.log("This app doesn't support the " + callArgs.uri.schemeName + " protocol.", "sample", "error");
                    }
                }
            }
        },
        ready: function (element, options) {
        }
    });
})();

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

The data passed in here for the contact send-message event 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".

(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/S2-Send-Message.html", {
        processed: function (element, messageArgs) {
            // messageArgs is the parameter passed to navigation in the activated event handler.
            if (messageArgs) {
                WinJS.log && WinJS.log("Send message activation was received. The service to use is " + messageArgs.serviceId + ". The user ID to message is " + 
                messageArgs.serviceUserId + ".", "sample", "status");
            }
        },
        ready: function (element, options) {
        }
    });
})();

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

The data passed in here for the contact map-request event 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".

(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("/html/S3-Map-Address.html", {
        processed: function (element, mapArgs) {
            // mapArgs is the parameter passed to navigation in the activated event handler.
            if (mapArgs) {
                var address = mapArgs.address;
                WinJS.log && WinJS.log("Map address activation was received. The street address to map is " +
                    (address.streetAddress ? address.streetAddress : "unspecified") + ".", "sample", "status");
            }
        },
        ready: function (element, options) {
        }
    });
})();

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