2013-02-09 14 views
7

Próbuję wykryć, czy urządzenie bluetooth jest obecnie połączone z urządzeniem z systemem Android przy użyciu interfejsu API 14 lub nowszego. Wygląda na to, że powinienem móc korzystać z metody BluetoothSocket.isConnected(), ale bez względu na to, co zrobiłem, do tej pory po prostu dostaję fałszywą odpowiedź za cokolwiek, połączoną lub nie.Android BluetoothSocket.isConnected zawsze zwraca wartość false

AndroidManifest obejmuje następujące linie:

<uses-permission android:name="android.permission.BLUETOOTH" /> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 

<!-- Locale 4.x supports API 14 or greater. --> 
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> 

<uses-feature android:name="android.hardware.bluetooth" /> 

a kod w pytaniu:

protected void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); 

    for (BluetoothDevice device : pairedDevices) { 
     Log.i(Constants.LOG_TAG, String.format(Locale.US, "Device: %s connected: %b", device.getName(), isConnected(device))); //$NON-NLS-1$z 
    } 
} 

private boolean isConnected(BluetoothDevice device) { 
    BluetoothSocket socket = null; 

    // Get a BluetoothSocket for a connection with the given BluetoothDevice 
    UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 
    try { 
     socket = device.createRfcommSocketToServiceRecord(SPP_UUID); 
    } catch (IOException e) { 
     Log.e(Constants.LOG_TAG, e.getMessage()); //$NON-NLS-1$z 
     return false; 
    } 

    Log.i(Constants.LOG_TAG, socket.toString()); //$NON-NLS-1$z 

    return socket.isConnected(); 
} 

są wyrzucane żadne błędy, po prostu wraca "false" 100% czasu. Czy jest coś, co nie robię dobrze?

Odpowiedz

0

Po pierwsze, dlaczego używasz refleksji ?! To dla mnie czerwona flaga. Interfejsy API umożliwiają rozmowę z innym urządzeniem przez Bluetooth, patrz this link, więc nie powinieneś używać odbicia.

Gniazdo zawsze zwróci niepodłączone przed wywołaniem metody connect. Wygląda na to, że twój kod uzyskuje gniazdo, ale nigdy nie próbuje nawiązać z nim połączenia. Najpierw musisz zadzwonić pod numer this method.

+0

Część refleksyjna pochodziła z zaakceptowanej odpowiedzi na to pytanie: http://stackoverflow.com/questions/3397071/service-discovery-failed-exception-using-bluetooth-on-android.Nie byłem zachwycony ideą refleksji, ale myślę, że pamiętam gdzieś indziej, że nie powinieneś polegać na UUID z pierwotnego pytania. Powiedziawszy to, ważną kwestią jest dla mnie druga część twojej odpowiedzi - Próbuję znaleźć jakiekolwiek podłączone urządzenia BT, a nie próbuję się połączyć. Czy to nie jest możliwe? Próbuję uniknąć konieczności tworzenia usługi monitorującej zmiany stanu BT. – jkane001

+0

Ameen miał rację, po bardziej uważnej lekturze odpowiedzi na SO i dokumentacji Android, zdałem sobie sprawę, że nie było tutaj potrzeby refleksji. Zaktualizowałem moje pierwotne pytanie lepszą metodą "isConnected", ale moje pytanie pozostaje: czy istnieje sposób na wykrycie, czy urządzenie BT jest połączone bez połączenia z nim? – jkane001

2

Wierzę, że jkane001 już rozwiązał swój problem, więc mam nadzieję, że ta odpowiedź pomoże komuś innemu.

Przede wszystkim po utworzeniu gniazda

socket = device.createRfcommSocketToServiceRecord(SPP_UUID); 

będziecie init, połączenie przez

socket.connect(); 

After, że będziesz w stanie sprawdzić stan połączenia za pomocą socket.isConnected()

Od connect() metoda jest nie blokuje, więc zaraz po podłączeniu gniazdo może nie być jeszcze podłączone. Proponuję użyć czegoś jak ten

while(!socket.isConnected() && trial++ < 3){ 
    try { 
     Thread.sleep(300); 
    } catch (Exception e) {} 
} 

Nawiasem mówiąc, uważam, że w przypadku niektórych urządzeń android isConnected() zawsze zwraca wartość false. W takim przypadku po prostu spróbuj napisać coś do gniazda i sprawdź, czy nie ma wyjątków.

+0

Znalazłem, że po utracie połączenia z powodu słabego sygnału, jeśli isConnected() jest wywoływana, nadal zwraca True. Tak więc uciekłem się do wysłania czegoś do gniazda i przechwycenia wyjątku. – VectorVictor

+0

@VectorVictor correct. isConnected() nie jest niezawodną metodą sprawdzania, czy połączenie jest aktywne. – Alex

2

Wygląda na to, że istnieją wersje urządzeń i/lub systemu Android, w których zaimplementowano metodę isConnected() (tzn. Funkcja istnieje i można ją nazwać), ale jest gorsza niż bezużyteczna, ponieważ zawsze zwraca wartość false. Na moim biurku z Androidem 4.2.2 mam telefon Alcatel, który wykazuje takie zachowanie.

Mój kod zakładał, że został odłączony, a więc zabity wątek połączenia i to doprowadzało mnie do szału przez długi czas. Jednak usunąłem wywołanie isConnected() i założyłem, że jest ono połączone i wszystko działa poprawnie! Nie znalazłem lepszego sposobu sprawdzenia poprawnego połączenia innego niż oczekiwanie na błąd i stwierdzenie, że połączenie nie działa. Zablokowany read() w wątku ostatecznie kończy się niepowodzeniem.

Mamy raporty z dziedziny, które brzmią podobnie, a 2 z 2 urządzeń problemowych, o których znamy wersję, również znajdują się w 4.2.2. Jeszcze nie wdrożyłem poprawki, więc nie jestem pewien, czy naprawił te przypadki.

Powiązane problemy