2013-07-20 24 views
11

Ho avuto questo problema per un po 'e non sono stato in grado di capirlo.android bluetooth non può connettersi

Ho un'applicazione Android che mette tutti i dispositivi associati in un listview. Quando si fa clic su una delle voci dell'elenco, verrà avviata una richiesta di connessione a tale dispositivo Bluetooth.

Posso ottenere l'elenco dei dispositivi con i loro indirizzi nessun problema. Il problema è che quando provo a connettermi ottengo una IOException su socket.connect();

Il messaggio di errore è la seguente: "connect lettura fallito, presa potrebbe chiuso o timeout, leggere ret: -1"

Ecco il mio codice. ANY suggerimenti sarebbero apprezzati. Sono abbastanza bloccato su questo.

fyi: il metodo "onEvent" è una libreria che semplifica i callback ... quella parte funziona. Quando l'utente fa clic su un voci di elenco Questo metodo viene chiamato "pubblico OnEvent void (evento EventMessage.DeviceSelected)"

public class EcoDashActivity extends BaseActivity { 

public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 


private BluetoothAdapter mBluetoothAdapter; 
private int REQUEST_ENABLE_BT = 100; 
private ArrayList<BluetoothDevice> mDevicesList; 
private BluetoothDeviceDialog mDialog; 
private ProgressDialog progressBar; 
private int progressBarStatus = 0; 
private Handler progressBarHandler = new Handler(); 


@Override 
public void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main); 

    mDevicesList = new ArrayList<BluetoothDevice>(); 

    // Register the BroadcastReceiver 
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
    registerReceiver(mReceiver, filter); 

    setupBluetooth(); 
} 

private void setupBluetooth() { 
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    if (mBluetoothAdapter == null) { 
     // Device does not support Bluetooth 
     Toast.makeText(this, "Device does not support Bluetooth", Toast.LENGTH_SHORT).show(); 
    } 

    if (!mBluetoothAdapter.isEnabled()) { 
     Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
    } else { 
     searchForPairedDevices(); 
     mDialog = new BluetoothDeviceDialog(this, mDevicesList); 
     mDialog.show(getFragmentManager(), ""); 
    } 

} 

private void searchForPairedDevices() { 

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); 
    // If there are paired devices 
    if (pairedDevices.size() > 0) { 
     // Loop through paired devices 
     for (BluetoothDevice device : pairedDevices) { 
      // Add the name and address to an array adapter to show in a ListView 
      mDevices.add(device.getName() + "\n" + device.getAddress()); 
      mDevicesList.add(device); 
     } 
    } 
} 


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 
      mDevicesList.add(device); 
     } 
    } 
}; 


@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    unregisterReceiver(mReceiver); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
if (requestCode == REQUEST_ENABLE_BT) { 
     if (resultCode == RESULT_OK) { 
      Toast.makeText(this, "BT turned on!", Toast.LENGTH_SHORT).show(); 
      searchForPairedDevices(); 

      mDialog = new BluetoothDeviceDialog(this, mDevicesList); 
      mDialog.show(getFragmentManager(), ""); 
     } 
    } 

    super.onActivityResult(requestCode, resultCode, data); 
} 


public void onEvent(EventMessage.DeviceSelected event) { 

    mDialog.dismiss(); 

    BluetoothDevice device = event.getDevice(); 

    ConnectThread connectThread = new ConnectThread(device); 
    connectThread.start(); 
} 


public 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; 

     // 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(MY_UUID); 
     } catch (IOException e) { } 
     mmSocket = tmp; 
    } 

    public void run() { 
     setName("ConnectThread"); 
     // 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 
      Log.d("kent", "trying to connect to device"); 
      mmSocket.connect(); 
      Log.d("kent", "Connected!"); 
     } catch (IOException connectException) { 
      // Unable to connect; close the socket and get out 
      try { 
       Log.d("kent", "failed to connect"); 

       mmSocket.close(); 
      } catch (IOException closeException) { } 
      return; 
     } 

     Log.d("kent", "Connected!"); 
    } 

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

Ecco il mio logcat. Abbastanza corto.

07-22 10:37:05.129: DEBUG/kent(17512): trying to connect to device 
07-22 10:37:05.129: WARN/BluetoothAdapter(17512): getBluetoothService() called with no BluetoothManagerCallback 
07-22 10:37:05.129: DEBUG/BluetoothSocket(17512): connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[98]} 
07-22 10:37:40.757: DEBUG/dalvikvm(17512): GC_CONCURRENT freed 6157K, 9% free 62793K/68972K, paused 7ms+7ms, total 72ms 
07-22 10:38:06.975: DEBUG/kent(17512): failed to connect 
07-22 10:38:06.975: DEBUG/kent(17512): read failed, socket might closed or timeout, read ret: -1 

L'ultima riga è nella sezione "Catch" di un try/catch ... sto solo la registrazione del messaggio di errore.

prega di notare, v'è circa 20 secondi tra "cercando di collegarsi al dispositivo" e "impossibile collegare"

+0

Quale versione di Android? Potrebbe essere un problema di stack con Jelly Bean avere uno stack bluetooth totalmente diverso, Disaccoppia e provare l'abbinamento prima e poi riprovare – Slartibartfast

+0

posta logcat anche – Slartibartfast

+0

@Slartibartfast Attualmente sto lavorando su 4.2.2 Nexus 4. io aggiornare domanda con logcat. –

risposta

14

Lo stack bluetooth fagiolo di gelatina è nettamente diversa dalle altre versioni.

Questo potrebbe aiutare: http://wiresareobsolete.com/wordpress/2010/11/android-bluetooth-rfcomm/

In sostanza: L'UUID è un valore che deve puntare a un servizio pubblicato sul proprio dispositivo embedded, non è generata solo in modo casuale. La connessione RFCOMM SPP a cui si desidera accedere ha un UUID specifico che pubblica per identificare quel servizio e quando si crea un socket deve corrispondere allo stesso UUID.

Se si utilizza il dispositivo 4.0.3 e versioni successive, utilizzare fetchUuidsWithSdp() e getUuids() per trovare tutti i servizi pubblicati e i relativi valori UUID associati. Per compatibilità con le versioni precedenti leggere l'articolo

+0

GetUUIDs() restituisce un elenco di ID. Come fai a sapere quale dovrebbe essere usato? –

+0

Ho appena provato ogni UUID che è tornato e ha avuto lo stesso problema. –

+0

Sei a conoscenza di un esempio di codice completo che posso copiare/incollare in una nuova app per testarlo? –

0

Ho ricevuto lo stesso messaggio di errore dopo aver collegato la presa una seconda volta . Ho semplicemente controllato se la presa è già collegata.

if(!mmSocket.isConnected()) 
      mmSocket.connect(); 

Stavo testando su Android 4.4.2 (Moto G).