I have an issue regarding Xamarin, Bluetooth via Andriod. When creating a socket when connecting
_socket.IsConnected is always true
I'm storing the MAC address to the latest connected device and is trying to reconnect to that device directly using.
await _socket.ConnectAsync()
That functions dosnt throw any exceptions even if the remote device is off from the start. To handle all this I have tried to implement my own "IsConnected" by actually sending data and see if I get any response, with a timeout.
However, if the connection failed due to the remote devices was turned off, I can never "reuse" the socket. I always get following error when calling again since the first one "passed" even with a device that is off:
_socket.ConnectAsync()
read failed, socket might closed, read ret: -1
Is there a way for me to "reset" the socket in some way? I have included the connection function here below if that makes any sence.
public async Task<IDevice> Connect(BluetoothUnit device) { if (_connected) return Device(device.Type, this); var pinCode = DeviceManagement.PinCode(device.Type); var bluetoothDevice = BluetoothAdapter.DefaultAdapter.GetRemoteDevice(device.MAC); var setPin = bluetoothDevice.SetPin(Encoding.ASCII.GetBytes(pinCode)); if (_bluetoothGatt is null) _bluetoothGatt = bluetoothDevice.ConnectGatt(Android.App.Application.Context, true, new BluetoothDisconnectCallback()); _deviceType = device.Type; if ((int)Android.OS.Build.VERSION.SdkInt >= 10) _socket = bluetoothDevice.CreateInsecureRfcommSocketToServiceRecord(UUID.FromString(STANDARD_SPP)); else _socket = bluetoothDevice.CreateRfcommSocketToServiceRecord(UUID.FromString(STANDARD_SPP)); try { _bluetoothGatt.Connect(); await _socket.ConnectAsync(); if (!await ConnectionSuccesful(Device(device.Type, this))) return default(IDevice); BluetoothAdapter.DefaultAdapter.CancelDiscovery(); _storage.Save(StorageKeys.LatestDevice, device); _connected = true; return Device(device.Type, this); ; } catch (Exception e) { EventLogger.TrackException(e, new Dictionary<string, string> { { $"Andriod.Bluetooth.Connect", "Error while connecting" }, { "Device", JsonConvert.SerializeObject(device) } }); return default(IDevice); } } private async Task<bool> ConnectionSuccesful(IDevice device) { try { return await TaskHelper.RunTask(new Task(() => { byte[] inputData = new byte[300]; var bytes = _socket.InputStream.Read(inputData, 0, inputData.Length); }), 250); } catch (Exception e) { var msg = e.Message; return false; } }
I found the issue, could be good for everyone to know regarding socket failure:This causes the error Java.IO.IOException: "read failed, socket might closed or timeout, read ret: -1
This was casued due to multiple threads calling _socket.ConnectAsync().
So check that you dont start more then one task
Answers
Your seem to be trying to combine both Bluetooth Classic and Bluetooth LE. You can't do that. What type of device are you trying to connect to - Classic or LE? If it is Bluetooth LE see my post for an example in the following thread https://forums.xamarin.com/discussion/90887/bluetooth-le-texas-instruments-sensortag-tutorial
I using Bluetooth Classic. Which part is related to Bluetooth LE?
I manage to get around a lot of issue by using following code and see if devices is connected instead of socket:
After reading some I guess bluetoothgatt shouldnt be used by me...
Thanks!
Correct
Still having issue with connecting, disconnecting and then connecting again when socket is casting following exception:
_socket.ConnectAsync() read failed, socket might closed, read ret: -1
I found the issue, could be good for everyone to know regarding socket failure:

This causes the error Java.IO.IOException: "read failed, socket might closed or timeout, read ret: -1
This was casued due to multiple threads calling _socket.ConnectAsync().
So check that you dont start more then one task