UPDATE
感谢所有试图以任何方式提供帮助的人。但经过大量研究后,我发现问题不在代码中。我连接的设备有一个bug。编写的代码现在完全符合数据。
我写了一个代码,创建一个连接到wifi套接字的线程和一个读取和写入数据的第二个线程。要读取数据,我使用匿名处理程序。当我使用Fragments时,我选择使用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();
}
}
}
}
如果我使用代码98触发mComandoReceiver中描述的命令,则在几次迭代之后套接字停止响应。 如果我只触发一次,则返回正常。我想找出为什么只有在循环运行命令几次后停止它。 注意:当我说循环时,我没有参考循环命令。 操作如下:请求命令,并且在接收到数据并确认接收的数据是正确的是发送新命令请求其余数据。只是为了澄清,硬件读取内存中的大量数据,并在请求时将其发送到应用程序。对不起英语不好。我说葡萄牙语