2013-06-05 8 views
5

Wykonuję aplikację na Androida, w której potrzebuję 2 lub więcej urządzeń, aby móc łączyć się z jednym urządzeniem przez Bluetooth. Kod służący do łączenia dwóch urządzeń w formie peer-to-peer działa, ale gdy próbuję połączyć się z innym, pojawia się wyjątek IOException, który mówi "Połączenie odrzucone", ponieważ gniazdo jest zamknięte i jako takie nie może zakończyć parowania. Błąd jest pokazany poniżej.Parowanie dwóch urządzeń z systemem Android z trzecim urządzeniem za pomocą 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 

Czytałem, że dla każdego połączenia musi istnieć inny identyfikator UUID, czy tak? W każdym razie, napisałem swój kod, jak pokazano poniżej, pobierając inny UUID z tablicy dla każdego nowego połączenia.

// 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); 
        } 
       } 


      } 
     } 

    } 

Ale nawet tak, mam inny błąd na trzecim komórkowego, który próbuję połączyć się z jednym, który ma już działające połączenie Bluetooth drugiego urządzenia, jak pokazano poniżej.

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 

Czy ktokolwiek może pomóc rozwiązać ten problem? Dziękuję Ci.

+2

+1 Za miłe pytanie –

+1

Dzięki za mate +1. :) – jpmastermind

Odpowiedz

0

Spróbuj zadzwonić pod numer cancelDiscovery() na swój telefon BluetoothAdapter przed utworzeniem połączenia z gniazdem. Może to rozwiązać Twój problem na komputerze java.io.IOException: Service discovery failed, który otrzymujesz.

+0

Już włączam wykrywanie Bluetooth tuż przed wykonaniem połączenia. – jpmastermind

+0

Spójrz na to pytanie http://stackoverflow.com/questions/8515572/service-discovery-failed-from-android-bluetooth-insecure-rfcomm – Neil

0

Wymyśliłem rozwiązanie mojego problemu.

W sposobie słuchania następnie dokonać połączenia, pisałem to w ten sposób:

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); 
      } 

i metoda dla urządzeń slave do podłączenia do 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); 
      } 
     } 
    } 

ten Projekt pomógł mi wymyślić to: https://github.com/polyclef/BluetoothChatMulti

Mam nadzieję, że to pomoże każdemu, kto ma ten sam problem. :)

Powiązane problemy