This project has moved. For the latest updates, please go here.

How to pair bluetooth scanner with Windows Phone 8

Topics: Bluetooth - Windows Phone 8, Samples
Jun 14, 2013 at 1:21 PM
In description to last version of libriary I saw that its support Windows Phone 8. I don't understand how Motorola CS3070 scanner could be paired with Windows Phone 8. Specifications for this scanner described, that its support: "HID keyboard wedge and Serial Port Profile (SPP)". As far as I know, none of this profiles doesn't supported by Windows Phone 8. Is it really possible to pair this devices?

Thank you.
Jun 14, 2013 at 2:08 PM
Windows Phone 8 supports Radio frequency communication (RFCOMM) protocol which is the base protocol for Serial Port Profile (SPP). So basically you can use SPP with Windows Phone. You can read additional info about Bluetooth profiles and protocols here: http://en.wikipedia.org/wiki/Bluetooth_profile#Serial_Port_Profile_.28SPP.29
Jun 14, 2013 at 4:09 PM
Edited Jun 14, 2013 at 4:12 PM
I try to pair KDC 200 (http://www.koamtac.com/kdc200.html) barcode reader to Nokia Lumia 620. At kdc 200 I try to use SPP profile (I haven't check SPP 2.0 one). Windows Phone 8 detect KDC 200, but KDC 200 doesn't want to set connection at all ("connection failed" message). If I tap on kdc 200 in the list of detected Bluetooth devices, Windows Phone shows message "connected" and just after several seconds - "disconnected" message, as if couldn't find needed profile. What's wrong?
Jun 17, 2013 at 6:15 AM
Don't worry. It's normal. The OS has nothing to do with your device, but your app has. So when you connect to the device from your app, it will connect (and won't disconnect until you close your app or disconnect it manually).
Jun 17, 2013 at 12:33 PM
Ok. Thank you. I'll try.

What profile is better to use: SPP or SPP 2.0?

Is it ok, that when I try to connect KDC 200 to Windows Phone 8 shows error message "Connection failed!" and that's all?
Jun 17, 2013 at 12:57 PM
I haven't heard of SPP 2.0. I can't find anything about it in google too.

Don't try to connect the device to phone. Connect the phone to the device (from your app).
Jun 25, 2013 at 1:08 PM
I use sample application from archive. When I press "Select" button, event occured
    // Code to execute if a navigation fails
    private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
    {
        if (Debugger.IsAttached)
        {
            // A navigation has failed; break into the debugger
            Debugger.Break();
        }
    }
after launch line:

PeerInformation pi = await bdp.PickDeviceAsync();

What did I do wrong?
Jun 25, 2013 at 2:27 PM
You didn't do anything wrong actually. The sample application is just one project from entire solution. If you open references of that project, you will see that there is missing reference "InTheHand.Phone.Bluetooth". Just delete this reference and add reference to "bin\Release\InTheHand.Phone.Bluetooth.dll".
Jun 26, 2013 at 1:37 PM
The problem was the wrong uri in \InTheHand.Phone.Bluetooth\InTheHand.Phone.Bluetooth\BluetoothDevicePicker.cs
f.Navigate(new Uri("/InTheHand.Networking.Bluetooth;component/BluetoothPickerPage.xaml", UriKind.Relative));
I changed for

f.Navigate(new Uri("/InTheHand.Phone.Bluetooth;component/BluetoothPickerPage.xaml", UriKind.Relative));

and everything is ok with connecting device.
Jun 26, 2013 at 1:57 PM
But one another question. Now bluetooth barcode reader connected successfully. After connecting I see "AT+LASTCONNECT" string at the listbox. When I scan something nothing is happen. What event should be triggered when I scan barcode?
Jun 28, 2013 at 6:24 AM
There is no event you can listen.

The first way is to start one infinite while (in a separate thread of course) like in the sample:
 while (reading)
            {
                IBuffer returnedBuffer = await socket.InputStream.ReadAsync(buffer.AsBuffer(), (uint)buffer.Length, Windows.Storage.Streams.InputStreamOptions.Partial);
                
                string s = System.Text.Encoding.UTF8.GetString(buffer, 0, (int)returnedBuffer.Length);

                if (!string.IsNullOrEmpty(s))
                {
                    if (s.IndexOf('\0') > -1)
                    {
                        s = s.Substring(0, s.IndexOf('\0'));
                    }

                    sb.Append(s);

                    // Only process when we have a complete line
                    if (sb.ToString().EndsWith("\r"))
                    {
                        Dispatcher.BeginInvoke(new Action<string>(this.InsertMessage), sb.ToString());
                        sb.Clear();
                    }
                }
            }
And the second way is to parse StreamSocket's input stream (which is RT stile) to the old fashion Stream and read byte by byte like this:
socket = new StreamSocket();
...
Stream s = socket.InputStream.AsStreamForRead();
int oneByte = inputStream.ReadByte();
Don't forget to include:
using System.IO;
to be able to use AsStreamForRead().

Note that int oneByte = inputStream.ReadByte() hangs the thread until data is received and the only way to stop the waiting is to dispose the inputstream and make a new connection.
Jun 28, 2013 at 11:21 AM
The problem was in the specified method ReadTest() of the simple application. To work properly with KDC 200 the code should be modified. Instead of
                // Only process when we have a complete line
                if (sb.ToString().EndsWith("\r"))
                {
                    Dispatcher.BeginInvoke(new Action<string>(this.InsertMessage), sb.ToString());
                    sb.Clear();
                }
code must be
                if (s.EndsWith("\r") __|| s.EndsWith("\n")__)
                {
                    Dispatcher.BeginInvoke(new Action<string>(this.InsertMessage), sb.ToString());
                    sb.Clear();
                }
since the end of the line is "\r\n".
Jun 28, 2013 at 1:06 PM
Of course you need to change the sample code to match with your particular case.

Glad to hear your managed to resolve all the problems.
Jul 1, 2013 at 6:19 AM
Thank you for help.
Jul 8, 2013 at 8:18 AM
What can I use to make the process of connection Windows Phone 8 to Bluetooth barcode reader more stable? The current sequence of connection is look like:
  1. If I don't use Bluetooth reader for quite a long time I should press some button to wake up the device before initiating connection from WinPhone. Usually I press "Connect" button to connect device to smartphone.
  2. After that I start connection (await bdp.PickDeviceAsync()) from Windows Phone 8, but sometimes connection doesn't happen and application crashes. Typical error is: "System.UnauthorizedAccessException: Invalid cross-thread access."
  3. Then I restart WinPhone 8 application (sometimes couple times) and initiate connection to specified device. After that connection set up properly.
The same error is occured if I try to connect WinPhone to a bluethooth device which is asleep state.

Probably some recipe already exists, how to stabilize the process of connection, at least how catch some kind of exception. Using try..catch when invoking await bdp.PickDeviceAsync() is useless, it never catches. Crashes always catches in the app.xaml.cs at the level
    private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
    {
        if (Debugger.IsAttached)
        {
            // An unhandled exception has occurred; break into the debugger
            Debugger.Break();
        }
    }
Jul 8, 2013 at 9:54 AM
"System.UnauthorizedAccessException: Invalid cross-thread access" means that you are trying to change something on the UI from a thread that is not the UI thread.
I guess that you are using Task.Run() which usually starts a new thread, but sometimes it uses the UI thread (if it considers that the UI thread is not enough busy).


If you give a specific code that throws the exception I'll be able to help you better.
Jul 8, 2013 at 11:25 AM
Edited Jul 8, 2013 at 11:26 AM
I found the source of the problem. It's quite easy to reproduce the problem. When bluetooth device is asleap, just try to connect to its picking the needed device from the list of paired bluetooth devices (await bdp.PickDeviceAsync()) on WinPhone app. After executing the code marked bold
            Task<Windows.Foundation.IAsyncAction> a = btDevSocket.ConnectAsync((Windows.Networking.HostName)host, BluetoothService.SerialPort);
            __await a;__
I got a error "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (Exception from HRESULT: 0x8007274C)"

How it's better to handle the probem?
Jul 8, 2013 at 12:00 PM
If I just catch event for infinite loop for InputStream, reset "reading" flag (in 32feet sample application) and then try to pickup the same device again I get pi = null:
                InTheHand.Phone.Bluetooth.BluetoothDevicePicker bdp = new InTheHand.Phone.Bluetooth.BluetoothDevicePicker();
                PeerInformation pi = await bdp.PickDeviceAsync();
                if (pi != null)
                {
                    Windows.Networking.HostName hn = new Windows.Networking.HostName(pi.HostName.RawName.ToString());

                    // do something with the device
                    System.Threading.ThreadPool.QueueUserWorkItem(ReadThread, hn);
                }
Sep 16, 2013 at 4:30 PM
Edited Sep 16, 2013 at 5:44 PM
Warlib wrote:
The problem was the wrong uri in \InTheHand.Phone.Bluetooth\InTheHand.Phone.Bluetooth\BluetoothDevicePicker.cs
f.Navigate(new Uri("/InTheHand.Networking.Bluetooth;component/BluetoothPickerPage.xaml", UriKind.Relative));
I changed for

f.Navigate(new Uri("/InTheHand.Phone.Bluetooth;component/BluetoothPickerPage.xaml", UriKind.Relative));

and everything is ok with connecting device.
Hi Warlib and AnTo0o,

Can you please let me know how you changed this? I have added BluetoothDevicePicker, BluetoothPickerPage and BluetoothService classes into my project to fix the issues but now I can't get a proper socket connection with Bluetooth device.

In ReadThread function, socket.ConnectAsync method always returns a task with those parameters;
Status : Waiting for activations
Method : Null
Result : Not Yet Computed

Any help would be appreciated

Thanks,

Cihan
Sep 26, 2013 at 6:28 PM
Hello every one i want to search bluetooth device through Windows Phone 8

Please provide me code , i want to search all unpaired device.
Coordinator
Feb 3, 2014 at 8:57 PM
On Windows Phone 8 you can only enumerate paired devices.