Introduction
This article describes how to create Windows 8.1 and Windows Phone 8 applications supporting App-to-App communication over Bluetooth. With these applications, the user can:
- send and receive text messages
- send pictures (Windows Phone 8 Application)
- receive and save pictures (Windows 8.1 Application)
The Windows Store application is running as a Bluetooth server and the Windows Phone application is running as a Bluetooth client.
In order to successfully support App-to-App communication over Bluetooth, you don’t need any specific peripherals like Wi-Fi router, USB cable. The Windows Phone and the computer or tablet running Windows 8.1 are self-sufficient regarding the Bluetooth communication.
Initially, when I started to write these samples, I wanted to use the PeerFinder API which is available on both platforms, unfortunately I didn't find any way to use this API to allow a communication between a computer running Windows 8.1 and a Windows Phone 8. Finally I decided to use Bluetooth Rfcomm for the communication between both platforms. This approach requires to pair both devices at least one time before launching the applications.
Once you are able to create a Windows Store application and a Windows Phone application talking to each other over Bluetooth, you can bundle a Windows Store application with a Windows Phone application which could be a companion application of the Windows Store application.
To build the sample the Visual Studio 2013, the Windows Phone 8 SDK are required.
Pairing devices
Before launching the applications you need to pair over Bluetooth the Windows Phone and the computer running Windows 8.1.
1. On the computer running Windows 8.1, select ”PC and Devices” settings page. Select “Bluetooth” settings page.
2. On the Windows Phone, ensure Bluetooth is ON. Select “Bluetooth” settings page and turn on Bluetooth.
3. On the computer, select the Windows Phone in the list of the Bluetooth device, and tap on the“Pair” button.
4. On the Windows Phone, accept the pair request.
5. On the computer, confirm the pairing.
6. On both devices, the peer devices should be displayed as connected.
7. The devices are now paired, you can launch the applications on both platforms.
Connecting the applications
1. On the computer running Windows 8.1, launch the Bluetooth Server application.
2. On the Windows Phone, launch the Bluetooth client application.
3. Check in the Settings section that the “Service Name” are the same, it’s mandatory to successfully connect the client application with the server application. The GUID is defined in the application source code and in the Windows 8 application manifest.
4. On the Windows Phone application navigate to “Connection” pivot. Select the computer name in the list of paired devices and tap on the “Connect” button.
5. As it’s the first application connection a dialog box appears on the computer running the server application. Allow the Windows application to use your Windows Phone
6. Once the connection is accepted on the server side, the client application state is displayed as “Connected”
7. The server application state is also displayed as “Connected”
8. The applications are now connected, you can exchange text messages and pictures between both applications.
Sending and receiving text messages
1. On the Windows Phone, navigate to the Messages pivot, enter a text and tap on “Send” button.
2. You should receive the same message on your application running on Windows 8.1.
3. You can also send a message from the Windows application towards the Windows Phone application.
4. And receive the message on the Windows Phone.
Sending and receiving pictures
1. On the Windows Phone, navigate to the “Files” pivot, and tap on “Select Picture” button.
2. Navigate among the albums and select the picture you want to send to the Windows Application.
3. Once the picture is selected, the path and the size of the picture are displayed on the screen.
4. Tap on the “Send Picture” button to send the picture.
5. On the computer screen the picture is displayed in the Files section
6. If you double-tap on the picture, the picture is displayed in full screen. At least you can save the picture on your hard drive if you tap on the “Save Image” button.
Using Bluetooth Rfcomm for the communication between Windows and Windows Phone applications
Once the connection is established between the Windows Phone application and the Windows application using Windows.Networking.Sockets.StreamSocket, both applications can exchange commands over Bluetooth Rfcomm.
With the current applications, a command can be a text message, a picture.
The syntax associated with a command is the following:
command=<BluetoothCommand>|[[<Attribute0Key>=<Attribute0>]|[<Attribute1Key>=<Attribute1>] ... |[<AttributeNKey>=<AttributeN>]...]]
For instance:
Message Command:
command=message|content=<Message Content>
Picture File Command:
command=picture|path=<Picture Path>|size=<Picture Size>|content=<Picture Content>
This model can be extended to support new companion scenarios, a command could transport Audio files, Video files, keyboard events, …
Building the sample applications
In order to build the Bluetooth server sample application for Windows Store and the Bluetooth client sample application for Windows Phone, make sure you have the basics installed:
1. a computer running Windows 8.1
2. a Windows Phone running Windows Phone 8
3. Visual Studio 2013,
4. Windows Phone 8 SDK.
Exploring the Windows Store Application project
The Windows Store Application project is a XAML based project.
- MainPage.xaml.cs contains the main page source code.
- App.xaml.cs contains the implementation of the App class.
- WindowsBluetoothRfcommServer.cs contains the implementation of the WindowsBluetoothRfcommServer class.
- ApplicationConfiguration.cs contains the source code used to store and retrieve the application settings in the local app store.
Shared source code between Windows and Windows Phone
- BluetoothService.cs contains the Service ID used for the Bluetooth Communication.
- BluetoothServer.cs contains the definition of the Bluetooth Server Interface.
- BluetoothDevice.cs contains the definition of the BluetoothDevice class.
- BluetoothCommand.cs contains the definition of the BluetoothCommand, BluetoothCommandMessage, BluetoothCommandPicture classes.
BluetoothRfcommServer states:
The Windows Application and the Windows Phone Application use the same Service Uuid to enable the communication between both applications. For the Windows Store application the Service Uuid is defined in the application manifest and in the source code.
The following section is added in the Capabilities of the manifest:
<Capabilities>
<CapabilityName="internetClient"/>
<CapabilityName="picturesLibrary"/>
<m2:DeviceCapabilityName="bluetooth.rfcomm">
<m2:DeviceId="any">
<m2:FunctionType="serviceId:17890000-0068-0069-1532-1992D79BE4D8"/>
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
The file BluetoothService.cs contains the declaration of the ServiceID as well:
publicclass BluetoothRfcommGlobal
{
// Service uuid: shared between the bluetooth server (Windows 8 Application) and the bluetoth client (Windows Phone Application)
publicstatic Guid BluetoothServiceUuid = new Guid("17890000-0068-0069-1532-1992D79BE4D8");
// Service display name: shared between the bluetooth server (Windows 8 Application) and the bluetoth client (Windows Phone Application)
publicstaticstring BluetoothServiceDisplayName = "My Bluetooth Rfcomm Service";
}
The WindowsBluetoothRfcommServer is instantiated in the App constructor.
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
this.Resuming += OnResuming;
BluetoothRfcommServer = new WindowsBluetoothRfcommServer(BluetoothServiceUuid, BluetoothServiceDisplayName, ApplicationConfiguration.AutoStart);
}
The WindowsBluetoothRfcommServer is Initialized and Started in the method OnNavigatedTo of MainPage class.
// Initialize Blutooth Server to check whether the bluetooth is on
if (((App.Current as App).BluetoothRfcommServer != null) && ((App.Current as App).BluetoothRfcommServer.GetState() == BluetoothServerState.Created))
{
BluetoothServerReturnCode r = await(App.Current as App).BluetoothRfcommServer.Initialization();
if ((r == BluetoothServerReturnCode.Success) && ((App.Current as App).BluetoothRfcommServer.AutoStart == true))
{
r = await(App.Current as App).BluetoothRfcommServer.Start();
}
if (r != BluetoothServerReturnCode.Success)
{
if ((r == BluetoothServerReturnCode.InitMissingCaps) || (r == BluetoothServerReturnCode.StartMissingCaps))
{
Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog("bluetooth.rfcomm Capability missing in the application manifest", "Windows Bluetooth Server");
await messageDialog.ShowAsync();
}
elseif ((r == BluetoothServerReturnCode.InitBluetoothOff) || (r == BluetoothServerReturnCode.StartBluetoothOff))
{
Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog("Bluetooth is off, bluetooth is required to launch the server", "Windows Bluetooth Server");
await messageDialog.ShowAsync();
}
elseif (r == BluetoothServerReturnCode.StartNotAdvertising)
{
Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog("Bluetooth Advertising Error, restart the application", "Windows Bluetooth Server");
await messageDialog.ShowAsync();
}
else
{
Windows.UI.Popups.MessageDialog messageDialog = new Windows.UI.Popups.MessageDialog("Error occurs while initializing the server", "Windows Bluetooth Server");
await messageDialog.ShowAsync();
}
}
}
Once the WindowsBluetoothRfcommServer is started, it’s waiting for incoming connection requests from client devices. When the application is connected, the WindowsBluetoothRfcommServer calls the method WindowsBluetoothRfcomm_ConnectionReceived.
void BluetoothRfcommServer_ConnectionReceived(IBluetoothServer sender, BluetoothDevice args)
{
ClearMessage();
AddLog("Connected with " + (App.Current as App).BluetoothRfcommServer.ConnectedDeviceDisplayName);
}
When the WindowsBluetoothRfcommServer is connected, it can receive Bluetooth commands, in that case the WindowsBluetoothRfcommServer calls the method BluetoothRfcommServer_CommandReceived.
void BluetoothRfcommServer_CommandReceived(IBluetoothServer sender, BluetoothCommand args)
{
AddLog("Command received " + args.ToString());
if (args.GetType() == typeof(BluetoothCommandMessage))
{
BluetoothCommandMessage bm = args as BluetoothCommandMessage;
if(bm!=null)
AddMessage("Message Received: " + bm.MessageContent);
}
elseif (args.GetType() == typeof(BluetoothCommandPicture))
{
RunOnDispatcherThread(() =>
{
BluetoothCommandPicture bp = args as BluetoothCommandPicture;
if (bp != null)
{
DisplayImage(bp.PictureContent);
if (bp.PictureContent.Length > 0)
{
_ImageBuffer = newbyte[bp.PictureSize];
if (_ImageBuffer != null)
Array.Copy(bp.PictureContent, _ImageBuffer, bp.PictureContent.Length);
}
}
});
}
}
Exploring the Windows Phone 8 Application project
The Windows Phone 8 Player Application project is a XAML based project.
- MainPage.xaml.cs contains the main page source code.
- App.xaml.cs contains the implementation of the App class.
- WindowsBluetoothRfcommClient.cs contains the implementation of the WindowsBluetoothRfcommClient class.
- ApplicationConfiguration.cs contains the source code used to store and retrieve the application settings in the local app store.
Shared source code between Windows and Windows Phone
- BluetoothService.cs contains the Service ID used for the Bluetooth Communication.
- BluetoothClient.cs contains the definition of the Bluetooth Client Interface.
- BluetoothDevice.cs contains the definition of the BluetoothDevice class.
- BluetoothCommand.cs contains the definition of the BluetoothCommand, BluetoothCommandMessage, BluetoothCommandPicture classes.
BluetoothRfcommClient states:
The Windows Application and the Windows Phone Application use the same Service Uuid to enable the communication between both applications. For the Windows Phone application the Service Uuid is defined in the source code in the file BluetoothService.cs which contains the declaration of the ServiceID as well:
publicclass BluetoothRfcommGlobal
{
// Service uuid: shared between the bluetooth server (Windows 8 Application) and the bluetoth client (Windows Phone Application)
publicstatic Guid BluetoothServiceUuid = new Guid("17890000-0068-0069-1532-1992D79BE4D8");
// Service display name: shared between the bluetooth server (Windows 8 Application) and the bluetoth client (Windows Phone Application)
publicstaticstring BluetoothServiceDisplayName = "My Bluetooth Rfcomm Service";
}
The WindowsBluetoothRfcommClient is instantiated in the App constructor.
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard XAML initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Language display initialization
InitializeLanguage();
// Show graphics profiling information while debugging.
if (Debugger.IsAttached)
{
// Display the current frame rate counters
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Prevent the screen from turning off while under the debugger by disabling
// the application's idle detection.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
// Call BluetoothRfcommClient constructor
BluetoothRfcommClient = new WindowsPhoneBluetoothRfcommClient(BluetoothServiceUuid, BluetoothServiceDisplayName, ApplicationConfiguration.AutoStart);
}
The WindowsBluetoothRfcommClient is Initialized in the method OnNavigatedTo of MainPage class.
protectedoverride async void OnNavigatedTo(NavigationEventArgs e)
{
// Check if BluetoothRfcommClient instance
if ((App.Current as App).BluetoothRfcommClient == null)
return;
// Check BluetoothRfcommClient State
// If State == BluetoothClientState.Created, the bluetooth client didn't start
if ((App.Current as App).BluetoothRfcommClient.GetState() == BluetoothClientState.Created)
{
BluetoothClientReturnCode r = await(App.Current as App).BluetoothRfcommClient.Initialization();
if (r != BluetoothClientReturnCode.Success)
{
if ((r == BluetoothClientReturnCode.InitMissingCaps) || (r == BluetoothClientReturnCode.StartMissingCaps))
{
MessageBox.Show("bluetooth.rfcomm Capability missing in the application manifest", "Windows Phone Bluetooth Client", MessageBoxButton.OK);
}
elseif ((r == BluetoothClientReturnCode.InitBluetoothOff) || (r == BluetoothClientReturnCode.StartBluetoothOff))
{
MessageBox.Show("Bluetooth is off, bluetooth is required to launch the client", "Windows Phone Bluetooth Client", MessageBoxButton.OK);
{
ConnectionSettingsTask connectionSettingsTask = new ConnectionSettingsTask();
connectionSettingsTask.ConnectionSettingsType = ConnectionSettingsType.Bluetooth;
connectionSettingsTask.Show();
}
}
elseif (r == BluetoothClientReturnCode.StartNotAdvertising)
{
MessageBox.Show("Bluetooth Advertising Error, restart the application", "Windows Phone Bluetooth Client", MessageBoxButton.OK);
}
else
{
MessageBox.Show("Error occurs while initializing the client", "Windows Phone Bluetooth Client", MessageBoxButton.OK);
}
return;
}
}
// Subscribe to CommandReceived, LogReceived and StateChanged
(App.Current as App).BluetoothRfcommClient.LogReceived += BluetoothRfcommClient_LogReceived;
(App.Current as App).BluetoothRfcommClient.CommandReceived += BluetoothRfcommClient_CommandReceived;
(App.Current as App).BluetoothRfcommClient.StateChanged += BluetoothRfcommClient_StateChanged;
// Update IsConnected state
UpdateIsConnectedAndImageLoaded();
// Fill the list of Paired Devices
FillListPairedDevices();
}
Once the WindowsBluetoothRfcommClient is initialized, the user can connect the application with the service running on a device running Windows 8.1 in that case the application calls the method ButtonConnect_Click.
private async void ButtonConnect_Click(object sender, RoutedEventArgs e)
{
if ((ListDevices.SelectedIndex >= 0) && (ListDevices.SelectedIndex < ListDevices.Items.Count))
{
BluetoothDevice d = ListDevices.Items[ListDevices.SelectedIndex] as BluetoothDevice;
if(d!=null)
{
BluetoothClientReturnCode r = await (App.Current as App).BluetoothRfcommClient.Connect(d);
if(r == BluetoothClientReturnCode.Success)
{
// Start Message loop
ClearMessage();
ClearFile();
}
}
};
}
When the WindowsBluetoothRfcommClient is connected, it can receive Bluetooth commands, in that case the WindowsBluetoothRfcommClient calls the method BluetoothRfcommClient_CommandReceived.
void BluetoothRfcommClient_CommandReceived(IBluetoothClient sender, BluetoothCommand args)
{
AddLog("Command received " + args.ToString());
if (args.GetType() == typeof(BluetoothCommandMessage))
{
BluetoothCommandMessage bm = args as BluetoothCommandMessage;
if(bm!=null)
AddMessage("Message Received: " + bm.MessageContent);
}
elseif (args.GetType() == typeof(BluetoothCommandPicture))
{
BluetoothCommandPicture bp = args as BluetoothCommandPicture;
if(bp!=null)
AddFile("File Received: " + bp.PicturePath);
}
}
When the WindowsBluetoothRfcommClient is connected, the user can send Bluetooth commands as well, in that case the application calls the method ButtonSend_Click.
private async void ButtonSend_Click(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(Message.Text))
{
BluetoothCommandMessage bm = new BluetoothCommandMessage();
if (bm != null)
{
bm.CreateMessageCommand(Message.Text);
BluetoothClientReturnCode r = await (App.Current as App).BluetoothRfcommClient.SendCommand(bm);
if (r == BluetoothClientReturnCode.Success)
AddMessage("Message Sent: " + Message.Text);
}
}
}
Downloading the projects
Download: C# (200 KB)
Requires: Windows 8.1, Windows Phone 8, Visual Studio 2013, Windows Phone 8 SDK
Last updated: 12/13/2013
License: MS-LPL
Technologies: Bluetooth, Rfcomm, StreamSocket, PeerFinder, C#, XAML
Topics: Windows Store and Windows Phone App-to-App communication over Bluetooth