2017-07-22 2 views
1

Problème

Comment puis-je distinguer entre l'impossibilité d'établir une connexion Bluetooth avec un appareil Android à distance parce que:Différencier entre "hors gamme" ou "à portée, mais pas de socket serveur d'écoute"? (Bluetooth)

  • Scénario 1: le dispositif à distance est hors de portée, ou son Bluetooth est désactivé.
  • scénario 2: le périphérique distant est à portée, mais il n'y a pas de socket serveur sur le périphérique distant pour accepter ma connexion.

Ce que j'ai essayé

  1. Je ne pouvais pas différencier les exceptions lancées lors de la connexion parce qu'il a jeté les exceptions identiques dans les deux cas:

    java.io.IOException: read failed, socket might closed or timeout, read ret -1 
    
  2. Je ne pouvais pas utiliser fetchUuidsWithSdp() pour vérifier si mon UUID pris en charge par le périphérique distant car il beha Ves la même manière dans les deux cas ... according to the documentation:

    Cette API est asynchrone et l'intention {@link de #ACTION_UUID} est envoyé, avec les UUID pris en charge par l'extrémité distante. S'il y a une erreur dans l'obtention des enregistrements SDP ou si le processus prend beaucoup de temps, l'intention {@link de #ACTION_UUID} est envoyé avec le UUID qui est actuellement présent dans le cache ...

    son comportement aussi semble en quelque sorte imprévisible selon this SO thread.

  3. enfin, je ne voulais pas utiliser sdpSearch de faire la différence entre les deux, parce que a été ajouté dans l'API 23, et je veux être en mesure de soutenir jusqu'à API 19.

Répondre

1

Vous pouvez déterminer si un périphérique est à portée en essayant de vous connecter à un UUID standard généralement disponible sur les périphériques Android. Si l'appel à se connecter:

  • échoue, le périphérique distant est hors de portée ou son Bluetooth est désactivé.
  • réussit, alors le périphérique distant est à portée et vous devez fermer la connexion et ensuite essayer de vous connecter à l'UUID de votre application ... si cela échoue, alors il n'y avait pas de socket d'écoute ... si elle réussit, alors tout est bien.

code Exemple:

public BluetoothSocket connect(BluetoothDevice remoteDevice) throws IOException 
{ 
    OPP_UUID = UUID.fromString("00001105-0000-1000-8000-00805f9b34fb"); 

    // check if remote device is in range...throw exception if out of range 
    try 
    { 
     BluetoothSocket socket = remoteDevice 
      .createRfcommSocketToServiceRecord(OPP_UUID); 
     socket.connect(); 
     socket.close(); 
    } 
    catch(IOException ex) 
    { 
     throw new IOException("out of range",ex); 
    } 

    // try to connect to service on remote device...throw exception if UUID 
    // is not available 
    try 
    { 
     BluetoothSocket socket = remoteDevice 
      .createRfcommSocketToServiceRecord(MY_UUID); 
     socket.connect(); 
     return socket; 
    } 
    catch(IOException ex) 
    { 
     throw new IOException("no listening server socket",ex); 
    } 
} 

J'utilisé BluetoothDevice.getUuids() pour obtenir les UUID disponibles sur un de mes appareils Android. Il m'a donné cette liste:

0000110a-0000-1000-8000-00805f9b34fb - Advanced Audio Distribution Profile (0x110a) 
00001105-0000-1000-8000-00805f9b34fb - Object Push Profile (0x1105) // least invasive one...it seems 
00001115-0000-1000-8000-00805f9b34fb - Personal Area Networking Profile (0x1115) 
0000112f-0000-1000-8000-00805f9b34fb - Phonebook Access (0x112f) // this works! 
00001112-0000-1000-8000-00805f9b34fb - Headset - Audio Gateway (0x1112) 
0000111f-0000-1000-8000-00805f9b34fb - Handsfree Audio Gateway (0x111f) 
00001132-0000-1000-8000-00805f9b34fb - Message Access Profile (0x1132) // this works too! 
00000000-0000-1000-8000-00805f9b34fb - Base UUID (0x0000) // couldn't get this to work :(

Standard UUIDs from Bluetooth spec.