Queuing Bluetooth Connection Request and accept then concurrently - android

In my Android application I can accept connection request sent from BT device(SPP profile). those BT devices sends connection request periodically and application accept it.
But now my problem is, I can pair with multiple device but wants to communicate with paired devices periodically. so i want clarification on this front.
If application communicate with one device and at same time another device sends connection request then can i accept this connection request through my App using BluetoothServerSocket? How?

Bluetooth Server can server up to 7 different bluetooth clients, you need to create bluetooth server socket in a separate thread and every time a client connects , send that client to a new thread , and return to listening state.
you can use the following pseudocode
BluetoothServerSocket serverSocket = BluetoothAdapter.listenUsingRfcommWithServiceRecord();
while(running){
BluetoothSocket client = serverSocket.accept(); //blocks untel a client is connected
sendClientToHisThread(client);
}
private void sendClientToHisThread(final BluetoothSocket socket){
Thread thread = new Thread(new Runnable(){
#Override
public void run(){
// communicate with client
socket.close();
}
});
thread.start();
}

I think you can follow the line on the BluetoothChat example, having a thread listening for incoming connections but, in your case, as a connection is established you do not close the server socket.

Related

Establishing Socket connection between Android and UWP app over WiFiDirect

I am trying to establish a socket connection between an Android and a UWP application over WiFiDirect. UWP application advertise itself enabling others to discover it. Android app search for available WiFiDirect device and connect with the UWP application.
I am successful in initialising and connecting over WiFiDirect between Android and UWP. But I am confused about creating Socket connection after WiFiDirect connection is made. More specifically I am hesitant on which side should i create ServerSocket and client-socket.
In Android side i have seen example of creating ServerSocket if the device is group-owner and vice-versa. But in UWP side I am not sure which one should i create.
Android side code to create socket:-
override fun onConnectionInfoAvailable(info: WifiP2pInfo?) {
if (info!!.groupFormed && info.isGroupOwner) {
// Creating ServerSocket
}
else if (info.groupFormed) {
// Creating Client Socket
}
}
On UWP side after connection request is received my sample code:-
private async void Listener_ConnectionRequestedAsync(
WiFiDirectConnectionListener sender,
WiFiDirectConnectionRequestedEventArgs args)
{
WiFiDirectConnectionRequest request = args.GetConnectionRequest();
WiFiDirectDevice _device = await WiFiDirectDevice.FromIdAsync(request.DeviceInformation.Id);
var endPoints = _device.GetConnectionEndpointPairs();
EndpointPair firstEndpoint = endPoints[0];
// Which socket connection should i create
// StreamSocket or StreamSocketListener
}
I have tried a hack in UWP which seems to work but I am not confident about it
if (firstEndpoint.LocalHostName.CanonicalName.EndsWith("1"))
{
// creating server socket
// StreamSocketListener and waiting for incoming connection
}
else
{
//Creating client socket
// StreamSocket and connecting with remote host
}
How should i decide create socket connection type in UWP side? Please provide the fundamental concept that i am missing here.

Android, Check if socket can send a message?

In my app I have a Socket like this:
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), 5000);
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
I write to this socket like this:
outputStream.write((message).getBytes());
And read from it like this:
while (true) {
try {
String message = inputStream.readLine();
if (message != null) {
//do sth here
}
} catch (IOException e) {
e.printStackTrace();
}
}
Now the problem is sometimes Internet connection is so slow, in a way that connection stays alive (socket stays connected) but cannot send any messages. In such conditions it seems like the OutputStream holds the messages until it is able to deliver them to server. All I want is know when the socket is in this state?
I can ask the above question in this way too: How can I know if the written message is delivered to server?
Note that checking whether device is connected to Internet or not doesn't help because the device is really connected but probably experiencing a poor connection.
All I want is know when the socket is in this state?
It gets in that state when TCP acks from the server are not received by the client so those packets can be removed from the client's outgoing buffer. As long as there is room in the buffer, a send will not block the caller. But once the buffer fills up, subsequent sends block the caller until the buffer clears up.
The only way I know to detect this condition is to use the socket's getChannel() method to access its underlying SocketChannel, and then register() that with a Selector that you can then monitor/query using its select() method to know if the socket is writable (has room in its outgoing buffer).
But, that will only be able to tell you if the socket can accept at least 1 byte for sending without blocking the caller. It will NOT tell you if a given message can be accepted completely for sending, as the buffer could fill up before the end of the message is reached, in which case the send will block until the buffer frees up room for the whole message.
But, it would let you monitor the health of the socket connection, and if you find that sends are getting blocked too much due to slow/missing acks, you might have to just close the socket and reconnect.
How can I know if the written message is delivered to server?
The only way is to have the server send back its own message after receiving the client's message.

create two socket connection in one thread

In my application i want to share file between a server and client, for that purpose i want to create two socket connection in one thread.
For example at server we have thread "T" and it has opened two socket like "1234" and socket no "3456" now on the client thread "T2" i will try to connect with these sockets.
So how i should implement it.
server:
thread
{
wait at socket "1234"
wait at socket "3456"
}
CLIENT SIDE:
Thread
{
connect with socket no "1234"
connect with socket no "3456"
}
if you have well implemented protocol(ie. each socket will send the data in a definite order), yeah one thread should work. but you can do this using only one socket connection too. what is the main point of creating two sockets? and what is the relation with android?
in addition; you definitely have to elaborate your question, otherwise it seems the question will be closed soon.

Android connect to server ip and port

what is the best approach of connecting android to server and ip and corresponding port? THis connection doesn't need to be all the time, but I am assuming I will send and recive files (in byte arrays or streams).
Thanks
Since the Android Development Tools are native to Java, you can use simple Java Socket APIs to accomplish this goal (see ServerSocket and Socket).
Server Code
You must start by opening a ServerSocket on your host computer by defining a port to listen on:
ServerSocket ss = new ServerSocket([some_port]);
Then you must begin listening for a client by calling ss.accept(). This method will block until a client connects:
Socket my_socket = ss.accept();
You now have a socket on your server that you can manipulate as you wish (probably through the use of ObjectInputStream and ObjectOutputStream):
ObjectOutputStream out = new ObjectOutputStream(my_socket.getOutputStream());
ObjectInputStream in= new ObjectInputStream(my_socket.getInputStream());
Client Code
You must establish a connection with the server that you have just created. You will do this by initializing a socket and passing in the IP address of your server (usually localhost for most testing purposes) and the port number on which your server is currently listening:
Socket socket = new Socket("localhost", [some_port]);
Again, establish some streams for communication:
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
And there you have it! You can now easily communicate with a server from an Android device. It is much simpler than you would think.
Please note, however, that this architecture implements TCP, which is much slower than UDP and will not work for any type of fast-paced data intensive games, but should accomplish your goals given your description above.

Dialog for incoming bluetooth request

In my application two devices are connected via bluetooth. In the background runs an own thread for the bluetooth connection. (Just like the example )
When one device wants to connect to another device i want a request dialog to be displayed on the second device.
So I guess that i have to modify the AcceptThread. The AcceptThread has to inform my mainThread (for example with a Handler).
In the AcceptThread I find this code:
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
Now here is my problem: this "blocking call" runs the whole time. How and when shall I inform my mainThread that another device wants to connect?
Definitely afterwards.
What you want is the result of the blocking call - of the .accept().
That is socket in your code.
Here is a quote from the Android BluetoothServerSocket documentation:
Then call accept() to listen for incoming connection requests. This
call will block until a connection is established, at which point, it
will return a BluetoothSocket to manage the connection. Once the
BluetoothSocket is acquired, it's a good idea to call close() on the
BluetoothServerSocket when it's no longer needed for accepting
connections. Closing the BluetoothServerSocket will not close the
returned BluetoothSocket.
So don't forget to do:
mmServerSocket.close()
After you receive a socket correctly - a BluetoothSocket actually -, you can choose what to do with it following the user's choice:
Should he go ahead, you just create the AsyncTask that reads from the socket until the AsyncTask is cancelled or an Exception occurs(on Bluetooth disconnect probably).
Should he decline, just cancel the socket
If you receive an Exception during the blocking call I would return to the main menu only a toast, saying something failed. But you can do a dialog (like retry?)

Categories

Resources