I have a simple chat over classic Bluetooth. The implementation is in Android/Java.
Problem
The whole mechanism works, in fact it allows you to send a message and it is received correctly. The only thing that when sending a second and third message... is not sent, however, I have seen that the log shows the following error:
W/IInputConnectionWrapper: beginBatchEdit on inactive InputConnection
getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper: getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper: getSelectedText on inactive InputConnection
W/IInputConnectionWrapper: endBatchEdit on inactive InputConnection
W/IInputConnectionWrapper: beginBatchEdit on inactive InputConnection
From what I understand is that the socket is somehow inactive and decides to close the Input communication.
Code
The code I have to send the messages is the following:
This method is used to obtain the elements of the chat, read what is in a EditText
message that I am going to send and when clicking on the send button it will transmit it over socket
private void init(){
listMainchat = findViewById(R.id.lista_conversacion);
edCreateMessage = findViewById(R.id.mensaje_entrada);
btnSendMessage = findViewById(R.id.btn_send_msg);
// Adaptador para poder indrucir elementos a la lista de la conmversacion
adapterMainChat = new ArrayAdapter<String>(context,R.layout.message_layout);
listMainchat.setAdapter(adapterMainChat);
btnSendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String message = edCreateMessage.getText().toString();
if(!message.isEmpty()){
edCreateMessage.setText(null);
chatUtils.write(message.getBytes());
}
}
});
}
This message is received by the following method: Which creates a Thread that manages the connection already established between both devices
public void write(byte[] buffer){
ConnectedThread conThread;
synchronized (this){
if(state != STATE_CONNECTED){
return;
}
conThread= connectedThread;
}
conThread.write(buffer);
}
public void write(byte[] buffer){
try {
outputStream.write(buffer);
handler.obtainMessage(MainActivity.MESSAGE_WRITE,-1,-1,buffer).sendToTarget();
}catch (IOException e){}
}
Edit
Searching in the Logs I have found this message in acatch
E/Connect->Run: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
What comes out of the Thread constructor of the socket connection:
private class ConnectThread extends Thread{
private final BluetoothSocket socket;
private final BluetoothDevice device;
// Constructor del Thread, recibimos un device
public ConnectThread(BluetoothDevice device){
// creamos un socket para el dispositivo remoto a travez de Bluetooth clasico (BD/EDR)
this.device = device;
BluetoothSocket tmp = null;
try{
tmp = device.createRfcommSocketToServiceRecord(APP_UUID);
}catch (IOException e){
Log.e("Connect->constructor", e.toString());
}
socket = tmp;
}
public void run (){
// Intentamos conectar al socket del dispositivo remoto
try{
socket.connect();
}catch (IOException e_){
Log.e("Connect->Run", e_.toString());
try{
Log.d("La ejecucion del trhead ha sido interrumpida",", vamos a cerrar el socket");
socket.close();
}catch (IOException e){
Log.e("Connect->CloseSocket", e.toString());
}
connectionFailed();
return;
}
synchronized (ChatUtils.this){
connectThread = null;
}
// Terminamos de conectar y notificamos al sistema de que estamos conectados
connected(socket,device);
}
public void cancel(){
try {
socket.close();
}catch (IOException e){
Log.e("Connect->Cancel", e.toString());
}
}
}
In the end, messing around, it turns out that the error was not in the write method, but in the read method, since, as they are implemented, the sockets are only prepared to listen for a single send within the
InputStream
. To solve this you have to put the method in a loop, in this way it is always listening, until an event occurs, such as the socket is closed or there is an exception (or leave it undefined with anwhile(true)
XDD )