Передача данных с использованием Wi-Fi сокетов внутри анонимного потока прекращается после нескольких итераций - ЗАКРЫТО - PullRequest
0 голосов
/ 02 апреля 2019

ОБНОВЛЕНИЕ

Спасибо всем, кто пытался помочь любым способом.Но после долгих исследований я обнаружил, что проблема не в коде.У оборудования, к которому я подключился, была ошибка.Написанный код будет идеально соответствовать данным.


Я написал код, который создает поток для подключения к сокету Wi-Fi и второй поток для чтения и записи данных.Для чтения данных я использую анонимный обработчик.Поскольку я использую фрагменты, я решил использовать LocalBroadcastManager для уведомления о необходимости отправки команд.Внутри обработчика я использую switch () для идентификации возвращаемых данных в соответствии с отправленной командой.Код работает для небольших объемов данных, но, используя цикл для чтения данных, он останавливается постоянно после нескольких итераций.Этот код используется для подключения к оборудованию, имеющему собственный Wi-Fi

. Я пытался поместить sleep () в run (), и даже тогда проблема не устранена.Я также установил таймер для активации, если он не получает данные после определенного периода, сокет выполняет метод run (), но не получает или не отправляет новый запрос.Кажется, по какой-то неизвестной причине сокет перестает общаться.Logcat не показывает никаких исключений.Он следует коду, используемому в main (), и коду 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();
            }
        }
    }


}

Если я вызову команду, описанную в mComandoReceiver, с кодом 98, то через несколько итераций сокет перестанет отвечать.
Если я запускаю только один раз, возврат работает нормально.Я хотел бы выяснить, почему только при повторении цикла он останавливается после выполнения команды несколько раз.
Примечание. Когда я говорю цикл, я не имею в виду команду цикла.
Операция заключается в следующем: команда запрашивается, и после получения данных и подтверждения правильности полученных данных отправляется новая команда, запрашивающая остальные данные.Просто чтобы уточнить, аппаратное обеспечение считывает объем данных в памяти и отправляет их в приложение по запросу.Извините за плохой английский.Я говорю по-португальски

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...