While working on our PDF viewer for Windows Phone 8 we stumbled on the pretty simple task,
that however became not that simple as it seemed from the first glance.
We needed to send a file via Bluetooth, and didn't want to spend much time for it, just call some
Windows Phone API and get things done. But it wasn't the case.
Apparently MS didn't make this API publicly available (if it exists), and developers are left on their own here. They have created a sample demonstrating how to enumerate paired Bluetooth devices or find devices by services supported using Service Discovery Protocol (SDP). It was quite useful but didn't demonstrate how to send a file, so we decided to go further and solve the puzzle.
MSDN sample says that profiles supported by Windows Phone 8 are:
- Advanced Audio Distribution Profile (A2DP 1.2)
- Audio/Video Remote Control Profile (AVRCP 1.4
- Hands Free Profile (HFP 1.5)
- Phone Book Access Profile (PBAP 1.1)
- Object Push Profile (OPP 1.1)
- Out of Band (OOB) and Near Field Communications (NFC)
Object Push Profile exists for a while and can be used for data exchange, it's based on OBEX protocol and many devices support it (for sure there're exclusions e.g. iPhone).
In order to send the file to other Bluetooth-enabled devices we would need to implement an OBEX OPP client, so we did.
Our implementation is based on IrOBEX spec v.1.3, that can be found by googling around. Other docs can be read as well, like Bluetooth spec (for OBEX FTP details)and various articles on the net.
So the code. We've implemented a simple class called BluetoothManager in C# that handles the sending task.Your app will need ID_CAP_PROXIMITY and ID_CAP_NETWORKING capabilities set.
I. Enumerating Bluetooth devices on Windows Phone
try
{ // look for paired devices and update our listbox
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
IReadOnlyList<PeerInformation> result = await PeerFinder.FindAllPeersAsync();
for (int i=0;i<result.Count;++i)
{
bluetoothDevices.Insert(i, result[i]);
}
}
catch (Exception ex)
{
// suggested by MS sample, handles BT radio off case
if ((uint)ex.HResult == 0x8007048F)
{
MessageBox.Show(AppResources.BluetoothIsOffMessageText, AppResources.AppMessageErrorCaption, MessageBoxButton.OK);
}}
II. Connecting and sending
using (BluetoothManager manager = new BluetoothManager(item))
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets//hello.txt"));
if (!await manager.SendFile(file,"hello.txt",BluetoothProfile.OBEXOPP, OnTransferProgress))
{
MessageBox.Show(AppResources.BluetoothSendFailed, AppResources.AppMessageErrorCaption, MessageBoxButton.OK);
}
}
One interesting thing regarding the OBEX OPP support by various devices is that we were able to get proper response packet from other Windows Phone devices, while not all Android devices responded properly.So we created a workaround for this behavior.
The complete code sample that includes OBEX OPP implementation needed for outgoing transfer is available for download, it's a Windows Phone App that enumerates paired devices and sends a simple file from its Assets. Here are a few screenshots.
We hope someone will find this code useful and we would appreciate your comments and suggestions.