Vous êtes sur la page 1sur 58

M12: Near Field

Communications and
Bluetooth
This App This App
Andy Wigley | Microsoft Technical Evangelist
Rob Tiffany | Microsoft Enterprise Mobility Strategist
Target Agenda | Day 1
Module and Topic | 10-minute breaks after each session / 60-minute meal break
Planned
Duration
1a - Introducing Windows Phone 8 Application Development | Part 1 50:00
1b - Introducing Windows Phone 8 Application Development | Part 2 50:00
2 - Designing Windows Phone Apps 50:00
3 - Building Windows Phone Apps 50:00
4 - Files and Storage on Windows Phone 8 50:00
Meal Break | 60-minutes 60:00
5 - Windows Phone 8 Application Lifecycle 50:00
6 - Background Agents 25:00
7 - Tiles and Lock Screen Notifications 25:00
8 - Push Notifications 30:00
9 - Using Phone Resources on Windows Phone 8 50:00
Target Agenda | Day 2
Module and Topic | 10-minute breaks after each session / 60-minute meal break
Planned
Duration
10 - App to App Communication 35:00
11 - Network Communication on Windows Phone 8 50:00
12 - Proximity Sensors and Bluetooth 35:00
13 - Speech Input on Windows Phone 8 35:00
14 - Maps and Location on Windows Phone 8 35:00
15 - Wallet Support 25:00
16 - In App Purchasing 25:00
Meal Break | 60-minutes 60:00
17 - The Windows Phone Store 50:00
18 - Enterprise Applications in Windows Phone 8: Architecture and Publishing 50:00
19 - Windows 8 and Windows Phone 8 Cross Platform Development 50:00
20 Mobile Web 50:00
Local Communication with Windows Phone
Bluetooth Overview
Using Bluetooth from an application
Near Field Communications (NFC)
Using NFC from an application
Agenda
Local Communication is new to Windows Phone 8
In Windows Phone 7 processes had to communicate using network connections
This was difficult because programs had to determine the required IP address
In Windows Phone 8 there are two new local communication methods available
Bluetooth
Can be used for phone to phone and phone to device communication over a range of
up to 10 meters
Near Field Communication (NFC)
Can be used for phone to device communication in very close proximity
Local Communication with Windows Phone 8
Bluetooth
Bluetooth is a short range wireless communication technology
Nominally the range is up to 10 metres, but this can be reduced by the conditions
There are two Bluetooth communication scenarios supported by Windows Phone
App to device
A program running on Windows Phone can establish connection to an external device
The Windows Phone must be paired with the device
App to app
A program running on a Windows Phone can find another application that is offering a
service that the device wishes to use; In this situation pairing is not required
The Bluetooth connection is provided to the program in the form of a StreamSocket
Bluetooth Scenarios
For App-to-Device scenarios, the device must have been paired with the phone
A device must be made discoverable before pairing can take place
Pairing is normally performed via the settings screen on the device
During the pairing the connection is authenticated
The user may need to enter a key to validate the connection
This may be a fixed key, as in the case of devices such as headsets, or generated by one
device and entered on the other
In an App-to-App Bluetooth connection, one app is looking for another instance of itself
on another phone
Can communicate without needing to be paired

Bluetooth Pairing
An application running on a Windows Phone 8 device
can obtain an enumeration of all the Bluetooth devices
that have been paired with the phone
The application can then attempt to make a connection
to the required service on
that device
For this to work the Bluetooth service on the phone
must be turned on
The ID_CAP_PROXIMITY and ID_CAP_NETWORKING
capabilities must be enabled for the application to
make use of the Bluetooth communications to a device

App to Device
The PeerFinder class can be used to search for paired devices







The search will fail with the exception shown above if Bluetooth is switched off
Finding Paired devices
try
{
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var peers = await PeerFinder.FindAllPeersAsync();
}
catch (Exception ex)
{
if ((uint)ex.HResult == 0x8007048F)
MessageBox.Show("Bluetooth is switched off");
}
If the user needs to turn Bluetooth on the application can open the appropriate Settings
page using the ConnectionSettingsTask launcher



Alternatively, use the LaunchUriAsync method:
Enabling Bluetooth
ConnectionSettingsTask connectionSettingsTask = new ConnectionSettingsTask();
connectionSettingsTask.ConnectionSettingsType = ConnectionSettingsType.Bluetooth;
connectionSettingsTask.Show();
Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth"));
A call to FindAllPeersAsync will return a list of PeerInformation values, each of
which describes a paired device that was discovered
This includes a display name for the host, the name of the service it provides and a
HostName value which gives more detail about the device




If no peers are found the list is empty , with a count of 0


Using the PeerInformation returned from PeerFinder
StringBuilder list = new StringBuilder();

foreach (PeerInformation p in peers)
{
list.AppendLine(p.DisplayName);
}
The ConnectAsync method will set up a StreamSocket that connects to a particular
service on the device
The application must search for the service that it wishes to interact with
The example below just connects to the service provided by the first peer found




The method will throw an exception if either parameter is null or empty


Connection to a remote device
// Just use the first Peer
PeerInformation partner = peers[0];

// Attempt a connection
StreamSocket socket = new StreamSocket();

await socket.ConnectAsync(partner.HostName, partner.ServiceName);
The Bluetooth discovery and connection methods provide the raw ability to transfer data
between the devices
This is the StreamSocket that is created as part of the setup process
The application will have to implement the communications protocol that is required for a
particular device
Messages in this format will need to be exchanged between the application and
the device
Interacting with Remote Devices via Bluetooth
App to App communication allows two programs to interact using Bluetooth to exchange
messages
An application can wait for and respond to messages from
another application
The PeerFinder class exposes an event which is raised when
a communication request is received from another system
The communication is still performed using a SocketStream
that links the two programs
The devices do not need to be paired in order to implement app to app connection
The ID_CAP_PROXIMITY capability must be enabled
App to App communication

An application can advertise itself as accepting connections by setting the display name
for the PeerFinder and then starting to advertise the service
Note that doing this for a long time may have an adverse effect on battery life



Advertising a Service for other Applications
// Register for incoming connection requests
PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;

// Start advertising ourselves so that our peers can find us
PeerFinder.DisplayName = "PSR";
PeerFinder.Start();
An application can subscribe to the ConnectionRequested event
When the event fires the application can then decide whether to accept the request
It could display a confirmation dialog to the user



Waiting for an Incoming Connection
// Register for incoming connection requests
PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;

// Start advertising ourselves so that our peers can find us
PeerFinder.DisplayName = "PSR";
PeerFinder.Start();
The above method creates a connection to an incoming request from RobsPhone
It uses the PeerInformation property of the ConnectionRequestedEventArgs to
determine who is attempting to connect



Responding to a Connection Request
StreamSocket socket;

async void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
{
if ( args.PeerInformation.DisplayName == "RobsPhone" )
{
socket = await PeerFinder.ConnectAsync(args.PeerInformation);
PeerFinder.Stop();
}
}
This checks the name of the incoming request and only responds to messages from
RobsPhone
The application could instead display a confirmation dialog for the user that identifies
the source of the request


Responding to a Connection Request
StreamSocket socket;

async void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
{
if ( args.PeerInformation.DisplayName == "RobsPhone" )
{
socket = await PeerFinder.ConnectAsync(args.PeerInformation);
PeerFinder.Stop();
}
}
This statement creates the socket
In a complete application there should be a handler for any exceptions that this action
might produce



Responding to a Connection Request
StreamSocket socket;

async void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
{
if ( args.PeerInformation.DisplayName == "RobsPhone" )
{
socket = await PeerFinder.ConnectAsync(args.PeerInformation);
PeerFinder.Stop();
}
}
This statement stops the phone from advertising the connection to other devices
This will prevent further requests and also improve power consumption



Responding to a Connection Request
StreamSocket socket;

async void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
{
if ( args.PeerInformation.DisplayName == "RobsPhone" )
{
socket = await PeerFinder.ConnectAsync(args.PeerInformation);
PeerFinder.Stop();
}
}
This method will read a string of text from the stream socket
The message is read as a length value, followed by that number of characters
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This is the DataReader that will be used to extract information from the StreamSocket
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This is the DataReader that will be used to extract information from the StreamSocket
The DataReader is created the first time the method is called
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This statement loads 4 bytes from the input stream
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This statement loads 4 bytes from the input stream
The incoming 4 bytes are converted into an integer, which is the number of bytes that are
being transferred
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This statement loads the text of the string
It uses the value that was supplied as the length
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This statement loads the text of the string
It uses the value that was supplied as the length
Once the bytes have been received, theyre converted into a string that is returned by the task
Application to Application Communication
private DataReader dataReader;

private async Task<string> GetMessage()
{
if (dataReader == null) dataReader = new DataReader(socket.InputStream);
await dataReader.LoadAsync(4);
uint messageLen = (uint)dataReader.ReadInt32();
await dataReader.LoadAsync(messageLen);
return dataReader.ReadString(messageLen);
}
This GetMessage method is a Task which can be started using the await keyword as
shown above
When the task completes the message will be set to the received string
Initiating the Read
string message = await GetMessage();
The SendMessage method is given a string that it sends to output stream
It uses a DataWriter to format the output
Writing the message
DataWriter dataWriter;

private async void SendMessage(string message)
{
if ( dataWriter == null)
dataWriter = new DataWriter(socket.OutputStream);

dataWriter.WriteInt32(message.Length);
await dataWriter.StoreAsync();

dataWriter.WriteString(message);
await dataWriter.StoreAsync();
}
The dataWriter is created from the socket if it does not already exist
Writing the message
DataWriter dataWriter;

private async void SendMessage(string message)
{
if ( dataWriter == null)
dataWriter = new DataWriter(socket.OutputStream);

dataWriter.WriteInt32(message.Length);
await dataWriter.StoreAsync();

dataWriter.WriteString(message);
await dataWriter.StoreAsync();
}
The first item that is written is the length of the string
Writing the message
DataWriter dataWriter;

private async void SendMessage(string message)
{
if ( dataWriter == null)
dataWriter = new DataWriter(socket.OutputStream);

dataWriter.WriteInt32(message.Length);
await dataWriter.StoreAsync();

dataWriter.WriteString(message);
await dataWriter.StoreAsync();
}
The first item that is written is the length of the string
This is followed by the string data itself
Writing the message
DataWriter dataWriter;

private async void SendMessage(string message)
{
if ( dataWriter == null)
dataWriter = new DataWriter(socket.OutputStream);

dataWriter.WriteInt32(message.Length);
await dataWriter.StoreAsync();

dataWriter.WriteString(message);
await dataWriter.StoreAsync();
}
This message transmitter method is not implemented as an awaitable
It can just be called when the message is to be sent
Writing the message
DataWriter dataWriter;

private async void SendMessage(string message)
{
if ( dataWriter == null)
dataWriter = new DataWriter(socket.OutputStream);

dataWriter.WriteInt32(message.Length);
await dataWriter.StoreAsync();

dataWriter.WriteString(message);
await dataWriter.StoreAsync();
}
The SendMessage and GetMessage methods implement each end of a simple protocol
that serialises a message between the sender and the receiver
If you want to send more complex data you can make use of appropriate serialisation
techniques to assemble the message text, just as you would between any processes which
are each end of a data channel
Messages and Protocols
demo
Bluetooth
App to App communication
over Bluetooth
It is not possible to use the emulator to debug a program that uses Bluetooth
An application can check to determine if the emulator is being used and
behave appropriately

Creating Bluetooth Solutions
if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator)
{
MessageBox.Show("No Bluetooth on the emulator");

}
Near Field
Communications
(NFC)
Near Field Communications provide a connection between devices that are very close
together (within 3-4 centimetres)
The data is transferred at a rate of up to 424 Kbits/second
It is assumed that this data transfer is intentional so there is not normally any
authentication as such
The user has positioned their device close to the other device
The phone can connect to an unpowered NFC chip/tag

Near Field Communications
NFC is best for sending small amounts of data between devices and can be used in a
number of different scenarios:
Connect devices.
Initiate a Bluetooth or WiFi Direct connection to your app on another device
Acquire content
read smart posters that contain digital content in an embedded NFC tag
Exchange digital objects
exchange an electronic business card, or vCard.
Using Near Field Communications
There are two ways that an application can use NFC
Simple transfer of a message from one device to another
An application can subscribe to message events and receive a string message of a
particular type
An NFC connection can be used to configure a connection which is implemented using
Bluetooth or WiFi
This extends the PeerFinder to allow an application to use NFC to quickly set up a
StreamSocket between two devices
Using NFC in applications
It is very easy to publish a message to NFC
Messages have a messagetype and a payload
The PublishMessage method returns an ID value that uniquely identifies the message that was sent
Messages are delivered to all applications that have subscribed to the message type
The PublishMessage method can only be used where the message type begins with Windows.
To publish messages by using another message type, like WindowsMime. or NDEF:WriteTag,
you must use the PublishBinaryMessage method
Publishing a Message
ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device!= null)
{
long id = device.PublishMessage("Windows.JumpStartMessageType", "Hello From Rob!");
}
The message is published everytime an NFC connection with another device is created,
until you stop publishing that message
Messages continue to be published until the StopPublishingMessage method is called
or the ProximityDevice object is released
Stop Publishing a Message
private void StopPublishingMessage(object sender, RoutedEventArgs e)
{
device.StopPublishingMessage(publishedMessageId);
publishedMessageId = -1;
}
The SubscribeForMessage method is given the message type and a delegate
In the above code the message type is Windows.JumpStartMessageType
You can add your own message types for your particular solution
Subscribing to Messages
ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device!= null)
{
long id = device.SubscribeForMessage ("Windows.JumpStartMessageType", messageReceived);

}
When a message is received the event is raised and the program can make use of the
received data
This event is fired when the received message has the same type
In the case of our program it will fire when a message of type
Windows.JumpStartMessageType is received
Receiving Messages
private void messageReceived(ProximityDevice sender, ProximityMessage message)
{
Dispatcher.BeginInvoke(()=>
MessageBox.Show("Message received " + message.DataAsString + " from " + sender.DeviceId)
);
}
If an application no longer wishes to subscribe to messages it can use the
StopSubscribingForMessage method to request this
The method is provided with the message id that was returned when the subscription was
first set up
An application may need to store this value in in case it is made dormant or tombstoned
when using Near Field Communications
Ending a subscription
device.StopSubscribingForMessage(id);
12/4/20
12
Microsoft
confidenti
4
7
demo
NFC
Exchanging small payload of data on Tap
In this usage, the PeerFinder class is used to search for other instances of itself on the
tapped device
Finding a Windows Phone Peer App using NFC
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();
}
Set the PeerFinder.AlternateIdentities property to allow connections to the Windows 8
version of your app
Finding a Windows 8 Peer App using NFC
ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device != null)
{
PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnStateChanged;

// Include the Windows 8 version of our app as possible peer
PeerFinder.AlternateIdentities.Add("Windows", "my Win8 appID");
// Start finding peer apps, while making this app discoverable by peers
PeerFinder.Start();
}
The event arguments contain a state change message
Setting up a StreamSocket using NFC
void OnTriggeredConnStateChanged(object sender, TriggeredConnectionStateChangedEventArgs args)
{
switch (args.State) {
case TriggeredConnectState.Listening: // Connecting as host
break;
case TriggeredConnectState.PeerFound: // Proximity gesture is complete setting up link
break;
case TriggeredConnectState.Connecting: // Connecting as a client
break;
case TriggeredConnectState.Completed: // Connection completed, get the socket
streamSocket = args.Socket;
break;
case TriggeredConnectState.Canceled: // ongoing connection cancelled
break;
case TriggeredConnectState.Failed: // Connection was unsuccessful
break;
}
}
The StreamSocket will be created using WiFi or Bluetooth to transfer the data
An application can configure the networking technologies by setting these properties
They are both set to true by default
Note that for a successful infrastructure network connection both devices must be
connected to the same subnet and be able to directly connect each other
It is advisable to make sure that Bluetooth is switched on before using this mechanism,
otherwise it might not be possible for the devices to connect in this way
Note that WiFi Direct is not supported on Windows Phone 8
Using the connection
PeerFinder.AllowBluetooth = true;
PeerFinder.AllowInfrastructure = true;
12/4/20
12
Microsoft
confidenti
5
2
demo
NFC and Bluetooth
Setting up a Bluetooth StreamSocket using NFC Tap to
Connect
An application running on a Windows Phone device can be interrupted at any time
An incoming phone call, text message or the user pressing the Start button will cause
the application to be made dormant and possibly tombstoned
When an application is made dormant all active network connections are disconnected as
it is no longer able to run in response to incoming messages
However, Windows 8 provides a reconnection feature that an application can use to
quickly re-establish a connection that was disrupted in this way
An application can persist connection configuration values that allows the socket to be
recreated when it resumes
Recreating a Connection
The statements above persist the RawName and RemoteServiceName properties of a socket
into the state storage for an application
If the application is resumed this information can be used to recreate the network
connection without having to make a new socket
This information could be stored in isolated storage if you wanted to make the application
re-establish the connection when it is launched
Need to be mindful of timeouts in this situation
Persisting connection information
PhoneApplicationService.Current.State["RemoteHostName"] =
socket.Information.RemoteHostName.RawName;
PhoneApplicationService.Current.State["RemoteServiceName"] =
socket.Information.RemoteServiceName;
When the application restarts it can recreate the connection by using the storage names
Both of the parties in the socket based connection should use this to allow them to
recover network connections
However, this option is not present on Windows 8, only on Windows Phone 8
Recreating a Socket
string storedRemoteHostRawName =
PhoneApplicationService.Current.State["RemoteHostName"] as string;
string storedRemoteServiceName =
PhoneApplicationService.Current.State["RemoteServiceName"] as string;

HostName newRemoteHostName = new HostName(storedRemoteHostRawName);

await socket.ConnectAsync(newRemoteHostName, storedRemoteServiceName);
Bluetooth and Near Field Communications (NFC) allow two Windows Phones to create
connections to each other and other devices
To connection a Bluetooth device it must be paired with the phone and support the service
that the application requests
Two applications can discover each other and exchange messages without pairing
The connection provided is surfaced as a StreamSocket
NFC allows a phone to exchange small amounts of data with another phone or device


Summary
Windows Phone 8 provides a means by which an NFC message can be used to instigate
a StreamSocket connection over Bluetooth or WiFi between two devices
Applications can store socket properties that allow connections to be resumed quickly
if the program is made dormant or tombstoned.
Summary continued
The information herein is for informational
purposes only an represents the current view of
Microsoft Corporation as of the date of this
presentation. Because Microsoft must respond
to changing market conditions, it should not be
interpreted to be a commitment on the part of
Microsoft, and Microsoft cannot guarantee the
accuracy of any information provided after the
date of this presentation.
2012 Microsoft Corporation.
All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION
IN THIS PRESENTATION.