0

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

  • I couldn't make head or tail of most of this, but you are misusing `available()`. There is a specific warning in the Javadoc against what you are doing here. Don't call it at all. Just block in `read()`, and make proper use of the count it returns. At present you are spin-looping. – user207421 Apr 01 '19 at 23:06
  • @user207421 - thanks for the reply. I tried to put as much code as I thought would be useful. Would you like some more explanation on the code? I did not understand the available () misuse. You could help me by explaining what I am doing wrong in more detail. Thank you again – Fabricius Lopes Apr 02 '19 at 00:06
  • You could have helped yourself over three weeks ago by consulting the Javadoc I mentioned, instead of waiting around here for an answer that may never come. – user207421 Apr 27 '19 at 07:05
  • Thank you. I read Javadoc and discovered that the problem was not in the code. – Fabricius Lopes Apr 28 '19 at 13:56

0 Answers0