UPDATE
Thanks to everyone who tried to help in any way. But after much research I discovered that the problem was not in the code. The equipment I connected to had a bug. The code written will perfectly fit the data now.
I wrote a code that creates a thread to connect to a wifi socket and a second thread to read and write the data. To read the data I use an anonymous handler. As I use Fragments I chose to use LocalBroadcastManager to notify the need to send commands. Inside the handler I use switch () to identify the return data according to the sent command. The code works for small amounts of data, but using a loop to read data, it stops constantly after a few iterations. This code is used to connect to hardware that has its own wi-fi
I tried to put sleep () inside of run () and even then the problem persisted. I also put a timer to activate if it does not receive data after a period, socket executes the run () method but does not receive or send a new request. It seems that for some unknown reason the socket stops communicating. Logcat does not show any exceptions. It follows the code used in main () and the code of Thread ().
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
btn_conectar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (btn_conectar.getText().toString().equals("Desconectar \nRegistrador")){
myThreadConnectWFdevice.cancel();
btn_conectar.setText("Conectar ao\nRegistrador");
btn_acessarregistrador.setText("Ativar Modo\nEnvio de Comandos");
btn_acessarregistrador.setEnabled(false);
btn_acessaronline.setText("Ativar Modo \nLeitura Online");
btn_acessaronline.setEnabled(false);
txt_disp_conectado.setText("Nenhum dispositivo");
}
else{ // Will connect to wifi network
if (!wifi.isWifiEnabled()) {
// Wifi is off and you need to create a dialog to ask if you can connect
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage("Deseja ligar a conexão WI-FI ?")
.setTitle("Conexão WI-FI desligada");
builder.setCancelable(false);
// Add the buttons
builder.setPositiveButton("Sim", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked OK button
wifi.setWifiEnabled(true); // liga o WIFI
btn_acessarregistrador.setEnabled(true);
SetNetwork(RedeConectada());
InicializaWF();
btn_conectar.setText("Desconectar \nRegistrador");
}
});
builder.setNegativeButton("Não", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
Toast.makeText(getApplicationContext(), "Operação cancelada pelo usuário.\nA conexão WI-FI permanece desligada", Toast.LENGTH_LONG).show();
}
});
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
dialog.show();
} else {
// WIFI on and connected to a network
btn_acessarregistrador.setEnabled(true);
SetNetwork(RedeConectada());
InicializaWF();
btn_conectar.setText("Desconectar \nRegistrador");
}
}
}
});
wifiIn = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
// super.handleMessage(msg);
if (msg.what == MESSAGE_READ) {
String readMessage = null;
try {
// Originally UTF8 but to have access to values above 128, you need to use ISO-8859-1.
readMessage = new String((byte[]) msg.obj, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
recDataString.append(readMessage);
switch ( STATUS_COMANDO){
case 98:
int qtdbytes;
int somapaginas;
int maiorvalor;
switch (tipocoleta) {
case 4:
qtdbytes = 2125;
// qtdbytes = 2128;
somapaginas = 4;
maiorvalor = 8189;
break;
}
if (recDataString.toString().contains("<READ>")) {
if ((recDataString.length() == qtdbytes) || ( recDataString.length() == qtdbytes+3)) {
pagstr.append( recDataString.substring( 0 , recDataString.length() -13 ) );
if (!CANCELA_COLETA) {
Intent intent = new Intent("coletar_loop8");
LocalBroadcastManager.getInstance( getApplicationContext() ).sendBroadcast( intent);
COLETANDO = 2;
}
}
}
};
STATUS_COMANDO = 0;
}
private void RegisterIntent() {
LocalBroadcastManager.getInstance(this).registerReceiver(
mComandoReceiver, new IntentFilter("SOCKET_OPENED"));
LocalBroadcastManager.getInstance(this).registerReceiver(
mComandoReceiver, new IntentFilter("SOCKET_CLOSED"));
LocalBroadcastManager.getInstance(this).registerReceiver(
mComandoReceiver, new IntentFilter("PERDA_CONEXAO"));
LocalBroadcastManager.getInstance(this).registerReceiver(
mComandoReceiver, new IntentFilter("coletar_loop8"));
}
private BroadcastReceiver mComandoReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case "coletar_loop8": // apenas o comando de ler o ponteiro , para uso nos loops
String selecaoloop8 = "";
switch (tipocoleta){
case 16 : selecaoloop8 = "$rw 00"+String.format("%04x", posponteiro)+"\r";
break;
default: selecaoloop8 = "$rd 00"+String.format("%04x", posponteiro)+"\r";
break;
}
final String comandoloop8 = selecaoloop8;
new Thread() {
public void run() {
try {
if (myThreadConnected != null) {
myThreadConnected.write(comandoloop8.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
STATUS_COMANDO = 98;
break;
}
}
};
public String RedeConectada(){
final ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final String ssid ;
String tempid="";
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
if (connectionInfo != null && !(connectionInfo.getSSID().equals(""))) {
tempid = connectionInfo.getSSID().replaceAll("\"","");
}
ssid= tempid;
return ssid;
}
public void SetNetwork(final String ssidrede){
if (!ssidrede.isEmpty()) {
final ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
NetworkRequest.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new NetworkRequest.Builder();
//set the transport type do WIFI
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(null);
// if (barCodeData.getSsid().contains("screenspace")) {
connectivityManager.bindProcessToNetwork(network);
// }
} else {
//This method was deprecated in API level 23
ConnectivityManager.setProcessDefaultNetwork(null);
}
connectivityManager.unregisterNetworkCallback(this);
}
});
}
}
}
public void InicializaWF(){
myThreadConnectWFdevice = new ThreadConnectWFdevice();
myThreadConnectWFdevice.start();
}
// Thread that connects via socket to wifi
private class ThreadConnectWFdevice extends Thread {
private ThreadConnectWFdevice() {
try {
serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
socket= new Socket();
socket.setKeepAlive(true);
} catch (IOException e) {
// Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
boolean success = false;
try {
socket.connect(new InetSocketAddress(serverAddr,SERVERPORT),3000);
success = true;
} catch (IOException e) {
e.printStackTrace();
success = false;
try {
Intent intent = new Intent();
intent.setAction("SOCKET_CLOSED");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
socket.close();
} catch (IOException e1) {
// Auto-generated catch block
e1.printStackTrace();
}
}
if(success){
Intent intent = new Intent();
intent.setAction("SOCKET_OPENED");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
myThreadConnected = new ThreadConnected(socket);
myThreadConnected.start();
SystemClock.sleep(500);
}else{
//fail
Intent intent = new Intent();
intent.setAction("PERDA_CONEXAO");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
}
public void cancel() {
Toast.makeText(getApplicationContext(),
"Conexão Encerrada ... ",
Toast.LENGTH_LONG).show();
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent();
intent.setAction("SOCKET_CLOSED");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
}
/*
ThreadConnected:
Background Thread to handle WIFI data communication
after connected
*/
private class ThreadConnected extends Thread {
private final Socket wifiSocket;
private final InputStream connectedInputStream;
private final OutputStream connectedOutputStream;
public ThreadConnected(Socket socketwifi) {
wifiSocket = socketwifi;
InputStream in = null;
OutputStream out = null;
OutputStreamWriter outt = null;
try {
in = socketwifi.getInputStream();
out = socketwifi.getOutputStream();
outt = new OutputStreamWriter(socketwifi.getOutputStream());
} catch (IOException e) {
// Auto-generated catch block
e.printStackTrace();
}
connectedInputStream = in;
connectedOutputStream = out;
mOutputStreamWriter = outt;
}
@Override
public void run() {
byte[] buffer ; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = connectedInputStream.available();
if(bytes != 0) {
//Log.w("Lendo", "bytes "+Integer.toString(bytes));
// buffer = new byte[1024];
//buffer = new byte[bytes];
if (COLETANDO == 2) {
SystemClock.sleep(2);
}
bytes = connectedInputStream.available(); // how many bytes are ready to be read?
buffer = new byte[bytes];
bytes = connectedInputStream.read(buffer, 0, bytes); // record how many bytes we actually read
wifiIn.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget(); // Send the obtained bytes to the UI activity
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public void writeHex(char[] buffer) throws IOException {
for(int k=0; k < buffer.length; k++){
new DataOutputStream(wifiSocket.getOutputStream()).writeByte(buffer[k]);
}
}
public void write(byte[] buffer) throws IOException {
connectedOutputStream.write(buffer);
}
public void cancel() {
try {
wifiSocket.close();
} catch (IOException e) {
// Auto-generated catch block
e.printStackTrace();
}
}
}
}
If I trigger the command described in mComandoReceiver with code 98, after a few iterations the socket stops responding.
If I trigger only once, the return works normally. I would like to find out why only when looping it stops after running the command a few times.
Note: When I say loop, I do not refer to the loop command.
The operation is as follows: A command is requested and upon receipt of the data and confirmation that the received data is correct is that a new command is sent requesting the rest of the data. Just to clarify, the hardware reads an amount of data inside a memory and sends it to the app when requested.
Sorry for the bad English. I speak Portuguese