Proximity for Windows Phone 8

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

Proximity refers to a set of classes in the Windows Runtime that support connections between devices that are within close range of each other. By using this API, your app can establish a connection through a tap, or by browsing for other devices that are running your app—peer apps—within wireless range. For example, one of these apps might be a multiplayer game in which two users tap their phones together to establish a shared game session. Or, an app might give users the ability to tap a computer and receive a link to a location where they can get more information or make a purchase. Windows Phone 8 supports Proximity communication using Near Field Communication (NFC). This topic provides an overview of the Proximity API for Windows Phone.

Note

We use the term device deliberately throughout this topic to indicate that proximity communication can take place between phones that are running Windows Phone 8, as well as between a Windows Phone 8 phone and a different type of device, such as a computer running Windows.

This topic contains the following sections.

Proximity scenarios

You can use Proximity for Windows Phone 8 in the following ways.

  • Connect devices. For example, you can use Proximity to simplify the process of connecting your app on one device to another instance of your app on another device over Wi-Fi or Bluetooth.

  • Acquire content. For example, through Proximity you can use your phone to read “smart” posters that contain digital content in an embedded NFC tag.

  • Exchange digital objects. For example, you can use your phone to exchange an electronic business card, or vCard.

Near Field Communication (NFC)

Near Field Communication (NFC) is an international standard for short-range wireless connectivity that provides intuitive, simple, and safe communication between electronic devices. NFC is the technology on the phone that makes Proximity scenarios possible. NFC has the following key characteristics.

  • Communication occurs when devices are within 3–4 centimeters (1 to 1.5 inches) of each other.

  • Communication is highly selective and intentional because users are intentionally bringing their devices together to connect.

  • The maximum theoretical data transfer rate is 424 kbits/s. The typical data transfer rates range from 30 kbits/s to 60 kbits/s.

  • Communication also can occur between an NFC device and an unpowered NFC chip, or tag.

Proximity API

The following tables list the primary Windows Runtime classes used in Proximity scenarios.

Class

Description

PeerFinder

Lets you discover another instance of your app on a nearby device and create a socket connection between the peer apps by using a tap gesture, or by browsing. A peer app is another instance of an app that is running on another device.

ProximityDevice

Makes your app able to communicate with other devices within an approximate range of 3–4 centimeters, and exchange a small payload of data during the tap.

PeerInformation

Contains information that identifies a peer.

ProximityMessage

Represents a message that's received from a subscription.

ConnectionRequestedEventArgs

Contains properties that are passed to an application with the ConnectionRequested event.

TriggeredConnectionStateChangedEventArgs

Contains properties that the TriggeredConnectionStateChanged event passes to an application.

Required capabilities

The following capabilities are required for NFC proximity scenarios. If these are not specified in the WMAppManifest.xml your application might not work correctly or it might fail the submission process to Store.

  • ID_CAP_NETWORKING 

  • ID_CAP_PROXIMITY

Proximity and tapping

Proximity and NFC enable you to connect two devices by tapping, or bringing them within millimeters of each other.  This scenario works with Windows Phone 8 and Windows 8 devices.  When a tap succeeds, you get back a socket that you can communicate with the other device. On Windows Phone 8, this socket is established on either a TCP/IP (Wi-Fi) connection or a Bluetooth connection. The Proximity API determines which connection to establish based on the values of the PeerFinder..::.AllowBluetooth and PeerFinder..::.AllowInfrastructure properties, which are true by default. The most consistent user experience, in terms of being able to tap and connect anywhere, is obtained when the devices wishing to connect have Bluetooth enabled. Wi-Fi connection is possible if both devices are on the same infrastructure network (same network or router, no IP conflicts, no firewalls, devices can ping each other). Therefore, it is recommended that your app informs the user before a tap attempt is made to make sure Bluetooth is enabled on both devices. You can do this by showing a message on the page or displaying a MessageBox. This is a transparent way of telling the user how to get the best tapping experience with their device.

Code examples

Sending and receiving NFC messages

This example shows you how to exchange data between apps that are running on two NFC-enabled devices. Use the ProximityDevice class to pass a simple string between the apps. The API provides default formatting, so this scenario is very easy to implement.

To send a message

Windows Phone apps only support one WriteTag message at a time. Before you can publish a new WriteTag message, you have to stop publishing any existing messages.

ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device!= null)
{
  long Id = device.PublishMessage("Windows.SampleMessageType", "Hello World!");
  Debug.WriteLine("Published Message. ID is {0}", Id);

  // Store the unique message Id so that it 
  // can be used to stop publishing this message
}

To receive a message

ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device!= null)
{
  long Id = device.SubscribeForMessage ("Windows.SampleMessageType", messageReceived);
  Debug.WriteLine("Published Message. ID is {0}", Id);

  // Store the unique message Id so that it 
  // can be used to stop subscribing for this message type
}

private void messageReceived(ProximityDevice sender, ProximityMessage message)
{
  
  Debug.WriteLine("Received from {0}:'{1}'", sender.DeviceId, message.DataAsString);
}

Finding a Windows Phone peer app

This example shows you how to use the PeerFinder class to look for a peer app.

To start looking for peers

ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device!= null)
{



     PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnectionStateChanged;

      // Start finding peer apps, while making this app discoverable by peers
      PeerFinder.Start();

}

To handle connection state changes

StreamSocket _streamSocket;
        
void OnTriggeredConnectionStateChanged(object sender, TriggeredConnectionStateChangedEventArgs args)
{
    switch (args.State)
    {
        case TriggeredConnectState.Listening:
            // Connecting as host
            break;
         case TriggeredConnectState.PeerFound:
            // Proximity gesture is complete and user can pull their devices away. Remaining work is to 
            // establish the connection using a different transport, like TCP/IP or Bluetooth
             break;
         case TriggeredConnectState.Connecting:
            // Connecting as a client
            break;
          case TriggeredConnectState.Completed:
            // Connection completed, retrieve the socket over which to communicate
            _streamSocket = args.Socket;
             break;
         case TriggeredConnectState.Canceled:
              break;
         case TriggeredConnectState.Failed:
             // Connection was unsuccessful
             break;
       }
}

Finding a Windows 8 peer app

To find peer apps on other platforms, such as Windows 8, you must first define the alternate app ID of your app on that platform.

ProximityDevice device = ProximityDevice.GetDefault();
if (device != null)
{
  PeerFinder.AlternateIdentities.Add("Windows", "my Win8 appID");
  PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnectionStateChanged;

  // Start finding peer apps, while making this app discoverable to peers
  PeerFinder.Start();
}

Foreground vs. background operation

When your proximity app is switched to the background, for example, when you answer a call, all published messages and subscriptions are suspended. There is no activity between devices when your app runs in the background, and this also means that no messages are queued for processing when your app is in the foreground again. Publication and subscription automatically resume when your app is once again in the foreground.

Encrypting the data stream using SessionKey

The underlying socket that is established for NFC is unprotected. The data channel is not encrypted by default. To encrypt the data being passed over this socket, and thereby reduce the risk of tampering, you can use the value of the SessionKey property on the StreamSocket as a symmetric key. This can be used in a cryptographic library, such as System.Security.Cryptography..::.AesManaged. This key is known only to the devices that are in proximity to each other.

Reconnecting peer phone apps

Because of resource constraints of the phone, your app will likely be tombstoned at some point. This is normal, to help maintain that buttery-smooth experience on the phone. Your app can be pushed to the background for many reasons: an incoming phone call, the user switches apps, an incoming text message, and so on. When your app is tombstoned, it loses resources, and any socket connection is disconnected. Your app also can lose socket connection when the user moves around, based on wireless connectivity that is available. This is expected, and because we wanted to make sure that the user has a good user experience, reconnect was introduced in Windows Phone 8. Through reconnect, a connection can be automatically reestablished after a brief loss of socket connection.

Note

Reconnect on Windows Phone 8 is supported only for Bluetooth and TCP/IP (Wi-Fi) connections.

To reconnect after a socket connection failure

  1. Save the RemoteHostName and RemoteServiceName property values when you establish your connection.

  2. In the Application_DeActivated event of your app, persist the RemoteHostName.RawName and RemoteServiceName values if there is an active socket connection, because this indicates that the app wants to reconnect when it resumes.

    string storedRemoteHostRawName = socket.Information.RemoteHostName.RawName;
    string storeRemoteServiceName = socket.Information.RemoteServiceName;
    
    // Persist these two values
    
  3. When your app is reactivated and resumes, call the PeerFinder..::.Start method as usual.

  4. Create a new RemoteHostName object using the storedRemoteHostRawName value you persisted in step 2.

    HostName newRemoteHostName = new HostName(storedRemoteHostRawName);
    
  5. Create a new socket and call ConnectAsync, passing in the storedRemoteServiceName and the newly created newRemoteHostName.

    await socket.ConnectAsync(newRemoteHostName, storedRemoteServiceName);
    

If both you and your peer follow this procedure, the ConnectAsync calls should complete successfully, and your apps will reconnect without tapping the phones together again.

Note

Calling cancel on the pending ConnectAsync call has no effect. The reconnect operation will still wait for the full timeout before trying to reconnect.

Note

If a Windows Phone 8 device attempts to reconnect with a Windows 8 device, it will fail because this reconnect operation is not supported on Windows 8.

Remarks

ProximityDevice..::.GetDefault()()() creates an instance of a Windows.Networking.Proximity..::.ProximityDevice class and activates the default proximity provider. However, since this is not a system wide, always available, resource make sure to store this object as a class member variable or a static variable so that it does not unintentionally go out of scope.

Testing Proximity

The Windows Phone Emulator does not have any built-in support for testing Proximity, requiring you test your NFC functionality using a Windows Phone 8 that supports NFC. If you want to test using the emulator, and simulate tapping a pair of emulators together, you can try out tools available from the community. For an example, see Proximity Tapper available at http://proximitytapper.codeplex.com. Note that this tool is a community project and is not officially supported by Microsoft.

See Also

Other Resources

Bluetooth for Windows Phone 8

Windows Phone 8: Networking, Bluetooth, and NFC Proximity for Developers (Build 2012)

Code Sample: PixPresenter