WP8 Proximity Simplified

Posted by a Dev Theologian Thursday, October 17, 2013 11:13:23 AM Categories: WP8

This blog post will cover the setup of my ProximityHelper class in your apps and help you implement the various scenarios for making proximity connections. You may want to read my introductory post on proximity and WP8 (which also includes my reasons for creating this “mini” library).

My class makes it easy to set up peer-to-peer (bi-directional) socket connections without having to implement the glue necessary to get the connection off the ground. It handles both the scenarios where you want a tap connection and the ones where you need to browse for a connection.

Setup

Setup is fairly easy. Go to the respository for Proximity Toy and grab the latest files. You need to copy the ProximityResources.* files from under the “ProximityToy\Resources” folder. Additionally copy the “ProximityToy\Helpers” folder  (and subfolders) to your the project (this will get the ProximityHelper class AND the SocketHelper class which will be covered in another blog post; it will also get the UI components that we use to connect to a client during a “polling for clients” scenario). Finally you need the “Coding4Fun.Toolkit.Controls” library from Nuget (we use this to display dialogs in your app).

Implementing Scenarios

If you look at Proximity Toy you see that I have 3 different scenarios. These are roughly the scenarios we need to implement. Proximity Toy uses the words “client” and “server” which is the not best choice of words I have for what is happening. A “server” either polls or initiates the “tap.” The “client” responds to a connection request (initiated by one of these methods). These are not the best uses of the words as once the “conversation” is initiated then the both sides can send and receive asynchronously to the other side. [Maybe “initiator”/”responder” is a better set of names].

Connect (Client) scenario

The “Connect (Client)” sets up a situation where one phone is really listening for a connection and will respond to the connection (client responds to a connect requests). Proximity Helper will actually prompt the user to make sure it’s OK to connect to the other phone (it also identifies the “DisplayName” which is provided to ProximityHelper by “server” phone). You initiate this scenario in code like this:

// In your code make "Client Polling" something meaningful to the other user (like a user name for instance)
ProximityHelper.Default.DisplayName = "Client Polling"; 
 
// false below indicates that this is not a server (so monitor for connections)
var result = await ProximityHelper.Default.GetConnectionAndSocket(false);
 
if(result) {
// ******************************************************
// Do your communication here using ProximityHelper.Default.Socket
// ******************************************************
}
 
// At some point when you are done with the connection, do this to close it
// NOTE: this might not be in the same routine, just make sure you close the connection before you exit
ProximityHelper.Default.CloseConnection(true);


Connect By Tap scenario

The “Connect By Tap” sets up an NFC initiated (2 phones tapping) connection. In the conversation, the phone using this setting is the “server.” You call code that looks like this (it’s very similar to the last example):

// Again, make "Server Non-Polling" something meaningful to the other user (like a user name)
ProximityHelper.Default.DisplayName = "Server Non-Polling";
 
// The first parameter (true) in the signature below puts the system in "server" mode where NFC is on, and
// we are awaiting some event that makes this phone aware of a client
// The second parameter (false) tells the Helper that we don't want to poll for clients. If this phone doesn't
// support NFC then this setting will be automatically toggled to true to poll
// (Remember our goal here is to dumb down the mechanism and make it easy to create a connection)
var result = await ProximityHelper.Default.GetConnectionAndSocket(true, false);
 
if (result) 
{
// ******************************************************
// Do your communication here using ProximityHelper.Default.Socket
// ******************************************************
}
 
// After you are done communicating, close the connection (and the communication) down.
// NOTE: this might not happen in this routine
ProximityHelper.Default.CloseConnection(true);

 
Don’t forget that if the phone doesn’t have NFC and you put it into non-polling server mode, we will still poll because non-polling server mode doesn’t make sense on a phone without NFC.

Connect (Polling Server) scenario

The “Connect (Polling Server)” does everything that the last one does except that it also sets up to poll for “clients” to connect to when it finds one (or more) it will prompt (via a dialog using the ConnectPrompt user control in “Helpers\UI”) the user for a “client” to try a connection with. Once a “client” has been selected the “client” phone will prompt if it’s ok to connect, and if it is then a socket is retrieved. The code to do this looks like this (if you’ve been paying attention it should be easy to guess what it looks like):

// Again, make "Server Polling" something meaningful to the other user (like a user name)
ProximityHelper.Default.DisplayName = "Server Polling";
 
// The first parameter (true) in the signature below puts the system in "server" mode where NFC is on, and
// we are awaiting some event that makes this phone aware of a client
// The second parameter (true) tells the Helper that we want to poll for clients. 
//
// BTW, in most cases this is what you will want to do for the server
var result = await ProximityHelper.Default.GetConnectionAndSocket(true, true);
 
if(result) 
{
    // ******************************************************
    // Do your communication here using ProximityHelper.Default.Socket
   // ******************************************************
}
 
// After you are done communicating, close the connection (and the communication) down.
// NOTE: this might not happen in this routine
ProximityHelper.Default.CloseConnection(true); // Note: true clears the list containing available clients

 

Client Tap scenario

There is also a fourth scenario that is hidden from the UI where we handle an NFC Tap for connection. In this last situation what happens is that the app on one phone is set in one of the “server” modes, and the other phone is not running the app; when the phones are tapped the phone not running the app will prompt the user to open the app or ignore; when they open the app, it launches with a querystring to your main page. We won’t go into the deep details on this, but ProximityHelper can respond to this type of situation and will automatically set up the connection for you. In most cases you want to respond to a tap and instantly get a connection. Here’s the code for that:

private async void handleTap(NavigationEventArgs e)
{
    // We still set the DisplayName 
    // (by now you should know that you want this to be something that is meaningful)
    ProximityHelper.Default.DisplayName = "Client Tap";
 
    // We pass this routine the NavigationEventArgs as well as a bool value.
    // A false for the the bool value indicates we want to just detect that we got the
    // tap QueryString.
    // A true here indicates that if there was a tap Querystring to go ahead and set up
    // a connection            
    // True is your most likely value
    var wasTapConnection = await ProximityHelper.Default.DetectTap(e, true);
 
    if(wasTapConnection)
    {
        // ***************************************************************
        // Do your communication here using ProximityHelper.Default.Socket
        // ***************************************************************
    
        // At some point when you are done communicating, do this to close down the connection
        ProximityHelper.Default.CloseConnection(true); // true indicates clearing list of 
                                                                                                                     // available clients
    }
}
 

Customization Opportunities

I did want to mention again that if you don’t like my Prompt for client classes you can make changes by editing the xaml of the “Proximity\Helpers\ProximityUI\ConnectPrompt.xaml” file. The big thing to remember is that we are using a little bit of XAML binding (nothing too tricky). Basically we bind the ClientList to the ItemSource of the peerList control (it’s a listbox in our example, but it could be a different type of control entirely if you like); This the ClientList collection includes an IsSelected value that we use to set visibility (using a Converter), so you can use the same thing. Text blocks in the individual rows are bound to the DisplayName property.

Additionally all the static text is stored in the “ProximityTool\Resources\ProximityResources.resx” file. It is also localizable as a result.

Final thoughts

You now have a library that will make things simple for making Proximity style connections. You are ready for my SocketHelper discussion (look for it later today or early tomorrow). [If you are impatient you can dig into the getData and sendData methods in the codebehind of the MainPage.xaml file to see how this works]. Again the sample project (and helper files) can be found at the Proximity Toy’s Repository.
Gravatar

Comments

Comments are closed on this post.
Site Map | Printable View | © 2008 - 2014 Intradynamics | Powered by mojoPortal | HTML 5 | CSS | Design by mitchinson