2016-03-24 5 views
0

Mein Bluetooth-Code empfängt die Daten, die ich ihm sende, nicht ordnungsgemäß. Es sagt, dass der Sockel geschlossen war.Android-App sendet/empfängt Daten nicht über Bluetooth: Socket bleibt unerwartet geschlossen

ADB Fehler:

03-24 11:09:01.189 6826-7480/com.team980.thunderscout W/System.err: java.io.IOException: bt socket closed, read return: -1 
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:442) 
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96) 

                   [ 03-24 11:09:01.190 25999:26018 I/   ] 
                   [JSR82][JBT] JBT bt_handle_session_disconnect_ind parms.ps_type:01 
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:  at java.io.InputStreamReader.read(InputStreamReader.java:231) 
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:  at java.io.InputStreamReader.read(InputStreamReader.java:181) 
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:  at com.team980.thunderscout.thread.ServerReadThread.run(ServerReadThread.java:48) 

ServerReadThread.java:

package com.team980.thunderscout.thread; 

import android.bluetooth.BluetoothSocket; 
import android.content.Context; 
import android.os.Handler; 
import android.os.Looper; 
import android.widget.Toast; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

public class ServerReadThread extends Thread { 
private final BluetoothSocket mmSocket; 

private Context context; 

public ServerReadThread(BluetoothSocket socket, Context context) { 
    mmSocket = socket; 

    this.context = context; 
} 

public void run() { 

    InputStream is; 

    try { 
     is = mmSocket.getInputStream(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return; 
    } 

    InputStreamReader isr; 

    try { 
     isr = new InputStreamReader(is, "UTF-8"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return; 
    } 

    StringBuilder sb = new StringBuilder(); 

    try { 

     int data = isr.read(); //TODO somehow the socket closes here, returning -1! This is bad! 

     while (data != -1) { 
      char theChar = (char) data; 
      sb.append(theChar); 
      data = isr.read(); 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    String message = sb.toString(); 

    try { 
     isr.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    postToastMessage("Found message: " + message); //TODO print result 

    // Send the obtained bytes to the UI activity - TODO put it in a DB 
    /*Intent broadcastIntent = new Intent(); 
    broadcastIntent.setAction("ThunderScout_RefreshData"); 
    context.sendBroadcast(broadcastIntent);*/ 
} 

/* Call this from the main activity to shutdown the connection */ 
public void cancel() { 
    try { 
     mmSocket.close(); 
    } catch (IOException e) { 
    } 
} 

public void postToastMessage(final String message) { 
    Handler handler = new Handler(Looper.getMainLooper()); 

    handler.post(new Runnable() { 

     @Override 
     public void run() { 
      Toast.makeText(context, message, Toast.LENGTH_LONG).show(); 
     } 
    }); 
} 
} 

ServerAcceptThread:

package com.team980.thunderscout.thread; 

import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothServerSocket; 
import android.bluetooth.BluetoothSocket; 
import android.content.Context; 
import android.os.Handler; 
import android.os.Looper; 
import android.widget.Toast; 

import com.team980.thunderscout.bluetooth.BluetoothInfo; 

import java.io.IOException; 
import java.util.UUID; 

public class ServerAcceptThread extends Thread { 
private final BluetoothServerSocket mmServerSocket; 

private BluetoothAdapter mBluetoothAdapter; 

private Context context; 

public ServerAcceptThread(Context context) { 
    // Use a temporary object that is later assigned to mmServerSocket, 
    // because mmServerSocket is final 
    BluetoothServerSocket tmp = null; 

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

    try { 
     // MY_UUID is the app's UUID string, also used by the client code 
     tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(BluetoothInfo.SERVICE_NAME, UUID.fromString(BluetoothInfo.UUID)); 
    } catch (IOException e) { 
    } 
    mmServerSocket = tmp; 

    this.context = context; 
} 

public void run() { 
    // Keep listening until exception occurs 
    while (true) { 
     BluetoothSocket socket; 
     try { 
      postToastMessage("Listening for incoming connections"); 
      socket = mmServerSocket.accept(); //TODO find cause of error 
     } catch (IOException e) { 
      e.printStackTrace(); 
      break; 
     } 
     // If a connection was accepted 
     if (socket != null) { 
      // Do work to manage the connection (in a separate thread) 

      postToastMessage("Connected to " + socket.getRemoteDevice().getName()); 

      ServerReadThread readThread = new ServerReadThread(socket, context); 
      readThread.start(); 
     } 
    } 
} 

/** 
* Will cancel the listening socket, and cause the thread to finish 
*/ 
public void cancel() { 
    try { 
     mmServerSocket.close(); 
    } catch (IOException e) { 

    } 
} 

public void postToastMessage(final String message) { 
    Handler handler = new Handler(Looper.getMainLooper()); 

    handler.post(new Runnable() { 

     @Override 
     public void run() { 
      Toast.makeText(context, message, Toast.LENGTH_LONG).show(); 
     } 
    }); 
} 
} 

ClientConnectionThread:

package com.team980.thunderscout.thread; 

import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothSocket; 
import android.content.Context; 
import android.os.Handler; 
import android.os.Looper; 
import android.widget.Toast; 

import com.team980.thunderscout.bluetooth.BluetoothInfo; 
import com.team980.thunderscout.data.ScoutData; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 
import java.util.UUID; 

public class ClientConnectionThread extends Thread { 
private final BluetoothSocket mmSocket; 

private BluetoothAdapter mBluetoothAdapter; 

private ScoutData scoutData; 

private Context context; 


public ClientConnectionThread(BluetoothDevice device, ScoutData data, Context context) { 
    // Use a temporary object that is later assigned to mmSocket, 
    // because mmSocket is final 
    BluetoothSocket tmp = null; 

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

    // Get a BluetoothSocket to connect with the given BluetoothDevice 
    try { 
     // MY_UUID is the app's UUID string, also used by the server code 
     tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(BluetoothInfo.UUID)); 
    } catch (IOException e) { } 
    mmSocket = tmp; 

    scoutData = data; 

    this.context = context; 
} 

public void run() { 
    // Cancel discovery because it will slow down the connection 
    mBluetoothAdapter.cancelDiscovery(); 

    try { 
     // Connect the device through the socket. This will block 
     // until it succeeds or throws an exception 
     mmSocket.connect(); 
    } catch (IOException connectException) { 
     // Unable to connect; close the socket and get out 
     try { 
      mmSocket.close(); 
     } catch (IOException closeException) { 
      closeException.printStackTrace(); 
     } 
     return; 
    } 

    postToastMessage("Successfully connected to server device"); 

    try { 
     OutputStream os = mmSocket.getOutputStream(); 
     OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8"); 

     postToastMessage("Writing data: " + scoutData.getTeamNumber()); 

     osw.write(scoutData.getTeamNumber()); 

     postToastMessage("Send complete!"); 

     osw.close(); 
     //mmSocket.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

/** Will cancel an in-progress connection, and close the socket */ 
public void cancel() { 
    try { 
     mmSocket.close(); 
    } catch (IOException e) { } 
} 

public void postToastMessage(final String message) { 
    Handler handler = new Handler(Looper.getMainLooper()); 

    handler.post(new Runnable() { 

     @Override 
     public void run() { 
      Toast.makeText(context, message, Toast.LENGTH_LONG).show(); 
     } 
    }); 
} 
} 

Ich arbeite seit Stunden ohne Ergebnis. Der ServerAcceptThread wird ständig im Hintergrund ausgeführt und wartet auf einen ClientConnectThread auf einem anderen Gerät, um ihn zu kontaktieren. Dann erzeugt der ServerAcceptThread einen ServerReadThread, um die Daten zu lesen, die der ClientConnectThread sendet, aber er liest die Daten nicht jedes Mal.

Der ServerAcceptThread wird von einem Dienst verwaltet, und ClientConnectThreads werden bei Benutzerinteraktion mit einem "Senden" -Button erzeugt.

Wenn Sie weitere Informationen benötigen, würde ich gerne zur Verfügung stellen.

Antwort

0

Es ist eine dumme Fehlermeldung, wie andere in diesem Bereich. Was es sagen sollte ist, dass der Peer die Verbindung geschlossen hat. Die Steckdose ist noch offen. Das Aufrufen von read() auf einem geschlossenen Socket oder das Schließen, während read() in einem anderen Thread ausgeführt wurde, würde (sollte) eine Ausnahme verursachen.

+0

Wie würde ich verhindern, dass der Peer die Verbindung dann schließt? – 19lmyers

+0

Sofern Sie den Code nicht steuern, können Sie nicht. – EJP

+0

Ich schreibe den Code an beiden Enden. Beide Seiten werden in der Frage geliefert. – 19lmyers

Verwandte Themen