Reputation: 326
I have an app that I need to function as a bluetooth server, it will listen on incoming bluetoooth connections and print the message sent from those devices. I have managed to make some progress though I fear that I have might made a mistake calling a blocking method in the main thread of my app, that is the User Interface thread. When I call clientSocket= serverSocket.Accept();
everything in my app stops, i use a switcher to call the method that has the above line, the switcher shows like its turning on but hangs due to a method that imolements a blocking call till a bluetooth device connects to the socket. How can I avoid that effect on the main thread of my app because I believe once a bluetooth device connects to the app then the blocking call will be removed and the switcher will resume to being checked. I have thought about using a new thread to accept the socket but how will I display the data received from the device to a UI TextView element I have in my app since manipulation of TextViews and other UI is not allowed from a non-UI thread, Thank you
server_switch.Click += (o, e) =>
{
//check the check status of the switch and start and disable gatt accordingly
Switch myswitch = o as Switch;
if (myswitch.Checked)
{
Log.Debug("Check Status Enabled", myswitch.Checked.ToString());
myswitch.Checked = true;
//switch the adapter mode and request for visibility
switch (_adapter.ScanMode)
{
case ScanMode.Connectable:
MakeVisibleFor300Seconds();
break;
case ScanMode.None:
MakeVisibleFor300Seconds();
break;
case ScanMode.ConnectableDiscoverable:
//do nothing, adapter in required mode
Log.Debug("Adapter Mode",
"Connectable Discoverable:" +
(_adapter.ScanMode == ScanMode.ConnectableDiscoverable).ToString());
break;
}
//create a new thread and run
var newThread= new SocketListener(display_data, serverSocket);
newThread.Start();
}
}
else
{
//the switch is disabled
Log.Debug("Check Status Enabled", myswitch.Checked.ToString());
}
};
Class for accepting new connections
//create a new class for listening on connections and displaying message to the textview
public class SocketListener : Thread
{
private TextView _data;
private BluetoothServerSocket mysocket;
private Stream output, input;
//declare default ctor for reflections
public SocketListener()
{
}
//declare the custom ctor
public SocketListener(TextView display, BluetoothServerSocket socket)
{
mysocket = socket;
_data = display;
}
//override run and implement a blocking call
public override void Run()
{
//NB: This implements a blocking call till a device connects
BluetoothSocket source_device = mysocket.Accept();
//get the input and output streams
output = source_device.OutputStream;
input = source_device.InputStream;
//check if data is available and write it to our object
StreamReader reader = new StreamReader(input);
string dat="";
string line;
while ((line = reader.ReadLine()) != null)
{
dat += line;
}
_data.Text = dat;
}
}
Upvotes: 0
Views: 177
Reputation: 62129
All the stuff about android, java, C#, xamarin, bluetooth, etc. is irrelevant. This question is essentially asking how to build a socket server application for a small number of clients, where "small" here means that you have the luxury of spawning one thread per client. (If you were to serve a large number of clients, then you would have to resort to a threadpool, but in your case that would be an unnecessary complication.)
The way we build a socket server application for a small number of clients is as follows:
serverSocket.Accept()
.MessagingCenter.Send()
.Upvotes: 1