2014-02-25 144 views
2

我想通過藍牙使用Python-bluez將數據從Android客戶端(Nexus 4)發送到Python服務器(Linux機器)。每當客戶端向OutputStream寫入一些字節時,就會拋出一個IO異常「Broken Pipe」。服務器也似乎它不接受任何連接雖經Android客戶端沒有拋出任何異常 「socket_name.connect()」從Android(客戶端)通過藍牙發送數據到Python(服務器)通過藍牙

Android客戶端:

public class MainActivity extends Activity { 
    private BluetoothSocket ClientSocket; 
    private BluetoothDevice Client; 
    private ConnectedThread Writer; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    public BluetoothAdapter mblue; 
    public void connect(View sender) 
    { 
     mblue = BluetoothAdapter.getDefaultAdapter(); 
     int REQUEST_ENABLE_BT = 1; 
     final TextView er = (TextView)findViewById(R.id.Error); 
     if(mblue == null) 
      er.setText("No Bluetooth!"); 
     else if (mblue.isEnabled()) { 
      er.setText(mblue.getAddress() + " " + mblue.getName()); 
     } 
     else{ 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
     } 
    } 

    public void disov(View sender) 
    { 

     final TextView er = (TextView)findViewById(R.id.Error); 
     boolean tr = mblue.startDiscovery(); 
     if(tr == true) 
     { 
      er.setText("Disovering !!"); 
     } 
     IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
     registerReceiver(mReceiver, filter); 

    } 
    public void start(View sender) 
    { 
     final TextView er = (TextView)findViewById(R.id.Error); 
     final TextView lol = (TextView)findViewById(R.id.editText1); 
     Writer.write(lol.getText().toString().getBytes()); 
     lol.setText(""); 

    } 
    public void send(View sender) 
    { 
     ConnectThread con = new ConnectThread(Client); 
     con.start(); 
    } 
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     public void onReceive(Context context, Intent intent) 
     { 
      String action = intent.getAction(); 
      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       // Get the BluetoothDevice object from the Intent 
       BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       // Add the name and address to an array adapter to show in a ListView 
       //mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 

       final TextView er = (TextView)findViewById(R.id.Error); 
       if(device.getAddress().equals("9C:2A:70:49:61:B0") == true) 
       { 
        Client = device; 
        er.setText("Connected with the target device!"); 
       } 
      } 
     } 
    }; 
    private class ConnectThread extends Thread { 
     private final BluetoothSocket mmSocket; 
     private final BluetoothDevice mmDevice; 

     public ConnectThread(BluetoothDevice device) { 
      // Use a temporary object that is later assigned to mmSocket, 
      // because mmSocket is final 
      BluetoothSocket tmp = null; 
      mmDevice = device; 
      UUID myuuid = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee"); 
      final TextView er = (TextView)findViewById(R.id.Error); 
      // 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(myuuid); 

      } catch (IOException e) {} 
      ClientSocket = mmSocket = tmp; 
      Writer = new ConnectedThread(ClientSocket); 
     } 

     public void run() { 
      // Cancel discovery because it will slow down the connection 
      mblue.cancelDiscovery(); 
      final TextView er = (TextView)findViewById(R.id.Error); 
      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) {} 
       return; 
      } 

      // Do work to manage the connection (in a separate thread) 
      //manageConnectedSocket(mmSocket); 
     } 

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



    public class ConnectedThread extends Thread { 
     private final BluetoothSocket mmSocket; 
     private final InputStream mmInStream; 
     private final OutputStream mmOutStream; 

     public ConnectedThread(BluetoothSocket socket) { 
      mmSocket = socket; 
      InputStream tmpIn = null; 
      OutputStream tmpOut = null; 

      final TextView er = (TextView)findViewById(R.id.Error); 
      // Get the input and output streams, using temp objects because 
      // member streams are final 
      try { 
       tmpIn = socket.getInputStream(); 
       tmpOut = socket.getOutputStream(); 
      } catch (IOException e) {} 

      mmInStream = tmpIn; 
      mmOutStream = tmpOut; 

      er.setText(er.getText() + "\n" + socket.toString()); 
     } 

     public void run() { 
      byte[] buffer = new byte[1024]; // 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 = mmInStream.read(buffer); 
        // Send the obtained bytes to the UI activity 
        // mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer) 
        //   .sendToTarget(); 
       } catch (IOException e) { 
        break; 
       } 
      } 
     } 

     /* Call this from the main activity to send data to the remote device */ 

     public void write(byte[] bytes) { 
      final TextView er = (TextView)findViewById(R.id.Error); 
      try { 
       mmOutStream.write(bytes); 

       //mmOutStream. 
      } catch (IOException e) 
       { 
        er.setText(e.toString()); 
       } 
     } 

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

Python的服務器:

from bluetooth import * 

server_sock=BluetoothSocket(RFCOMM) 
server_sock.bind(("",PORT_ANY)) 
server_sock.listen(1) 

port = server_sock.getsockname()[1] 

uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee" 

advertise_service(server_sock, "SampleServer", 
        service_id = uuid, 
        service_classes = [ uuid, SERIAL_PORT_CLASS ], 
        profiles = [ SERIAL_PORT_PROFILE ], 
#     protocols = [ OBEX_UUID ] 
        ) 

print("Waiting for connection on RFCOMM channel %d" % port) 

client_sock, client_info = server_sock.accept() 
print("Accepted connection from ", client_info) 

try: 
    while True: 
     data = client_sock.recv(1024) 
     if len(data) == 0: break 
     print("received [%s]" % data) 
except IOError: 
    pass 

print("disconnected") 

client_sock.close() 
server_sock.close() 
print("all done") 

任何幫助表示讚賞。

回答

0

您已經使用了兩個公開課,即public class MainActivity extends Activity{}public class ConnectedThread extends Thread {}。但是在Java中,在一個JavaClass文件中應該有一個公共類和許多其他類。因此,從該文件中刪除public class ConnectedThread extends Thread {},然後在同一個包中創建一個新的Java類:public class ConnectedThread extends Thread {}