2013-06-05 8 views
5

sto facendo un'applicazione Android in cui ho bisogno di 2 o più dispositivi di essere in grado di connettersi a un dispositivo tramite Bluetooth. Il codice per collegare due dispositivi insieme in un modulo peer-to-peer funziona, ma quando provo a collegarne un altro ottengo una IOException che dice "Connessione rifiutata" perché il socket è chiuso e, come tale, non è in grado di completare l'accoppiamento. L'errore è mostrato sotto.accoppiamento di due dispositivi Android ad un terzo dispositivo tramite Bluetooth

Socket closed. Unable to complete pairing. 
java.io.IOException: Connection refused 
    at android.bluetooth.BluetoothSocket.connectNative(Native Method) 
    at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:216) 
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:270) 
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:1) 
    at android.os.AsyncTask$2.call(AsyncTask.java:264) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
    at java.lang.Thread.run(Thread.java:856) 
Could not connect to this device 

Ho quindi letto che deve avere un UUID diverso per ogni connessione, giusto? Comunque, ho scritto il mio codice come mostrato di seguito, prendendo un UUID diverso da un array per ogni nuova connessione.

// Unique UUID for this application 
    private static int indexUUID = 0; 
    private static final UUID[] MY_UUID_SECURE = {UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d168"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d169"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d170"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d171"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d172")}; 
    private static final String NAME_SECURE = "GridFrameworkSecure"; 

    /** 
    * Method to connect securely to Bluetooth device using it's MAC address 
    * @param macAddress valid Bluetooth MAC address 
    */ 
    public boolean connectSecurelyToDevice(BluetoothAdapter btAdapter, String macAddress){ 
     BluetoothDevice device = btAdapter.getRemoteDevice(macAddress); 
     ConnectAsyncTask connectTask = new ConnectAsyncTask(); 
     BluetoothSocket deviceSocket = null; 
     try { 
      deviceSocket = connectTask.execute(device).get(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
      return false; 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
      return false; 
     } 
     if(deviceSocket!=null){ 
      if(serverBluetoothNode==null){ 
       try { 
        serverBluetoothNode = new BluetoothNode(deviceSocket); 
        Log.i("bluetooth manager", "You are now a slave node."); 


        return true; 
       } catch (IOException e) { 
        e.printStackTrace(); 
        return false; 
       } 
      } else { 
       Log.e("bluetooth manager", "You already have a master."); 
       return false; 
      } 
     } else return false; 
    } 

    /** 
    * Method to allow this Bluetooth device to accept connection from another Bluetooth device 
    */ 
    public void allowSecureConnectionFromRemoteDevice(BluetoothAdapter btAdapter){ 
     AcceptConnectionAsyncTask acceptTask = new AcceptConnectionAsyncTask(); 
     acceptTask.execute(btAdapter); 
    } 

    private class ConnectAsyncTask extends AsyncTask<BluetoothDevice, Void, BluetoothSocket> { 

     @Override 
     protected BluetoothSocket doInBackground(BluetoothDevice... params) { 
      BluetoothDevice device = params[0]; 
      BluetoothSocket socket = null; 

      // Get a BluetoothSocket for a connection with the 
      // given BluetoothDevice 
      try { 
       socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE[indexUUID]); 
      } catch (IOException e) { 
       Log.e("Bluetooth Pairing", "create() failed", e); 
      } 

      Log.i("Bluetooth Pairing", "BEGIN ConnectThread SocketType: Secure"); 

      // Make a connection to the BluetoothSocket 
      try { 
       // This is a blocking call and will only return on a 
       // successful connection or an exception 
       socket.connect(); 
       Log.i("bluetooth manager", "You have connected a slave node to this one."); 

       return socket; 
      } catch (IOException e) { 
       Log.e("Bluetooth Pairing", "Socket closed. Unable to complete pairing.", e); 
       // Close the socket 
       try { 
        socket.close(); 
        indexUUID++; 
       } catch (IOException e2) { 
        Log.e("Bluetooth Pairing", "unable to close() socket during connection failure", e2); 
       } 
      } 

      return null; 
     } 

    } 

    private class AcceptConnectionAsyncTask extends AsyncTask<BluetoothAdapter, Void, Void> { 

     @Override 
     protected Void doInBackground(BluetoothAdapter... params) { 
      BluetoothServerSocket serverSocket = null; 
      String socketType = "Secure"; 

      // Create a new listening server socket 
      try { 
       serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]); 
      } catch (IOException e) { 
       Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "listen() failed", e); 
       indexUUID++; 
      } 

      Log.d("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + 
        "BEGIN mAcceptThread" + this); 

      BluetoothSocket socket = null; 

      // Listen to the server socket if we're not connected 
      while (true) { //mState != STATE_CONNECTED) { 
       try { 
        // This is a blocking call and will only return on a 
        // successful connection or an exception 
        socket = serverSocket.accept(); 
        Log.i("Slave", "server socket found");      

        // If a connection was accepted 
        if (socket != null) { 
         BluetoothNode node = null; 
         try { 
          node = new BluetoothNode(socket); 
          Log.i("connected to", node.getDeviceInformation()); 
          slaveBluetoothNodes.add(node); 

          indexUUID++; 
        serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]); 

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

          indexUUID++; 
          serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]); 
         } 
        } 
       } catch (IOException e) { 
        Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "accept() failed", e); 

        try { 
         indexUUID++; 
         serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]); 
        } catch (IOException e1) { 
         Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "listen() failed", e1); 
        } 
       } 


      } 
     } 

    } 

Ma anche così, ottengo un errore diverso sul terzo cellulare che sto cercando di connettersi a uno che ha già una connessione Bluetooth lavorando a un secondo dispositivo, come illustrato di seguito.

Socket closed. Unable to complete pairing. 
java.io.IOException: Service discovery failed 
    at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:406) 
    at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:217) 
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:270) 
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:1) 
    at android.os.AsyncTask$2.call(AsyncTask.java:185) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    at java.lang.Thread.run(Thread.java:1019) 
Could not connect to this device 

Qualcuno può aiutarci a capirlo? Grazie.

+2

+1 per Nizza domanda –

+1

Grazie per il +1 compagno. :) – jpmastermind

risposta

0

provare a chiamare cancelDiscovery() sul BluetoothAdapter prima di creare la connessione socket. Questo potrebbe risolvere il tuo problema sul java.io.IOException: Service discovery failed che stai ricevendo.

+0

Sto già disattivando Bluetooth Discovery appena prima di effettuare la connessione. – jpmastermind

+0

Dai un'occhiata a questa domanda http://stackoverflow.com/questions/8515572/service-discovery-failed-from-android-bluetooth-insecure-rfcomm – Neil

0

Ho capito la soluzione al mio problema.

Nel metodo per ascoltare quindi effettuare il collegamento, ho scritto in questo modo:

UUID[] MY_UUID_SECURE = {UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d168"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d169"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d170"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d171"), 
                UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d172")}; 

BluetoothServerSocket serverSocket = null; 
      BluetoothSocket socket = null; 

      try { 
       // Listen for all UUIDs in array 
       for (int i = 0; i < MY_UUID_SECURE.length; i++) { 
        serverSocket = btAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[i]); 
        socket = serverSocket.accept(); 
        if (socket != null) { 
         BluetoothNode node = null; 
         node = new BluetoothNode(socket); 
         Log.i("connected to", node.getDeviceInformation()); 
         slaveBluetoothNodes.add(node); 

         // add node to database 
         databaseManager.insertToGridTree(node.getDeviceAddress(), "slave", "active", node.getDeviceName()); 
        }      
       } 
      } catch (IOException e) { 
       Log.e("Accept Bluetooth Pairing Thread", "accept() failed", e); 
      } 

E il metodo per i dispositivi slave per il collegamento al master:

BluetoothDevice device = params[0]; 
    BluetoothSocket socket = null; 

    Log.i("Bluetooth Pairing", "BEGIN ConnectThread SocketType: Secure"); 

    // Get a BluetoothSocket for a connection with the 
    // given BluetoothDevice 
    for(int i=0; i<MY_UUID_SECURE.length; i++){ 
     try { 
      socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE[i]); 
      // This is a blocking call and will only return on a 
      // successful connection or an exception 
      socket.connect(); 
      Log.i("bluetooth manager", "You have connected a slave node to this one."); 

      return socket; 
     } catch (IOException e) { 
      Log.e("Bluetooth Pairing", "create() failed", e); 
      Log.i("Bluetooth Pairing", "trying another UUID"); 
      try { 
       socket.close(); 
      } catch (IOException e2) { 
       Log.e("Bluetooth Pairing", "unable to close() socket during connection failure", e2); 
      } 
     } 
    } 

Questo progetto mi ha aiutato a capire questo: https://github.com/polyclef/BluetoothChatMulti

Spero che questo aiuti chiunque abbia lo stesso problema. :)

Problemi correlati