2011-02-14 25 views
17

Para mi aplicación, estoy intentando emparejar mediante programación un dispositivo bluetooth. Puedo mostrar el cuadro de diálogo de emparejamiento para el dispositivo que quiero emparejar y puedo ingresar un código PIN. Cuando presiono "Pair", el diálogo se elimina y no ocurre nada.Cómo asociar mediante programación un dispositivo bluetooth en Android

Solo necesito compatibilidad con dispositivos con Android 2.0 y versiones posteriores.

Actualmente estoy usando el siguiente código para iniciar el progreso de apareamiento:


public void pairDevice(BluetoothDevice device) { 
     String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST"; 
     Intent intent = new Intent(ACTION_PAIRING_REQUEST); 
     String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE"; 
     intent.putExtra(EXTRA_DEVICE, device); 
     String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT"; 
     int PAIRING_VARIANT_PIN = 0; 
     intent.putExtra(EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN); 
     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(intent); 
    } 

Antes de iniciar una solicitud de vinculación que detener la exploración de nuevos dispositivos.

Mi aplicación tiene los siguientes permisos: bluetooth

  • android.permission.BLUETOOTH_ADMIN
  • android.permission.BLUETOOTH
+2

pasé varios días l buscando una solución a este problema exacto. parece que Google considera que el emparejamiento forzado es un problema de seguridad, por lo que los tipos de ACCIÓN que ha enumerado aquí en realidad no existen. Encontré la clase que hace referencia aquí: http://developer.oesf.biz/em/developer/reference/cinnamon/android/bluetooth/BluetoothDevice.html#ACTION_PAIRING_REQUEST pero no está en los documentos oficiales: http: // developer .android.com/reference/android/bluetooth/BluetoothDevice.html – moonlightcheese

+0

@FireFLy ¿tiene alguna solución? – Pawan

+0

¿tiene la solución? –

Respuesta

0

Puede ser que usted necesita para startActivityForResult en lugar de solamente startActivity?

Otra opción es buscar en el ejemplo de la aplicación BluetoothChat e iniciar un socket de conexión RFComm, tan pronto como inicie el socket aparecerá automáticamente una solicitud de emparejamiento sin necesidad de enviar un intento por separado para el emparejamiento. De esta forma, no necesitará manejar el emparejamiento.

http://developer.android.com/resources/samples/BluetoothChat/index.html

-2

además de mi comentario, por cierto, incluso si estos tipos de acción existiera, esa no es la forma de usarlos. he aquí un ejemplo:

Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); 
intent.putExtra(EXTRA_DEVICE, device); 
int PAIRING_VARIANT_PIN = 272; 
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN); 
sendBroadcast(intent); 
+3

Lo intenté y no funciona. – Derzu

-1

He encontrado que el uso de valores diferentes para el resultado PAIRING_VARIANT_PIN en diferentes comportamientos de emparejamiento de interfaz de usuario.

Ver esta página: http://code.google.com/p/backport-android-bluetooth/source/browse/trunk/backport-android-bluetooth201/src/backport/android/bluetooth/BluetoothDevice.java?spec=svn67&r=67

Sospecho que el problema que tiene es que ambos dispositivos son Bluetooth 2.1, en cuyo caso, una solicitud de vinculación debe dar lugar a una clave de acceso de 6 dígitos que se muestra en los dos dispositivos.

El mejor resultado que pude lograr fue el uso de PAIRING_VARIANT_PIN = 0. Cuando mi aplicación me lo solicitó, ingresé el pin 1234 y apareció una clave de acceso de 6 dígitos en mi dispositivo de destino. La interfaz de usuario de emparejamiento terminó y eso fue todo.

O necesita saber cómo iniciar una solicitud de emparejamiento de Bluetooth 2.1, utilizando alguna otra variante de emparejamiento o pin de sincronización de emparejamiento. O bien, no está captando el resultado de la actividad que se está ejecutando correctamente.

Dado el tiempo que he estado tratando de hacer esto, he decidido que mis usuarios finales solo tendrán que emparejar usando la configuración de Android antes de usar mi aplicación.

+0

@Peter O. Stack Overflow me notifica que ha editado esto. Como esta es mi primera publicación, tengo algunas preguntas, si no te importa: - No puedo recordar mi mensaje original, así que no puedo ver lo que eliminaste. ¿Hay alguna forma de hacer esto? - ¿Tiene alguna solución a la pregunta por casualidad? - ¿Hay alguna manera de enviar mensajes a los usuarios directamente, en lugar de hacer lo que estoy haciendo ahora? Gracias de antemano. – user1007074

+0

1. Haga clic en la fecha después de la palabra "editada" para ver el historial de edición. 2. No, no tengo una solución al problema, ya que no estoy familiarizado con el tema. 3. No, no directamente, como en mensajes privados. Pero si el usuario tiene al menos 100 reputación y el otro tiene al menos 20 reputación, el usuario anterior puede [crear una sala de chat en la galería] (http://chat.stackoverflow.com/rooms/new) e invitar al otro usuario para entrar –

3

Por desgracia, creo que lo mejor que vas a conseguir es la apertura de Configuración/Wireless & redes/Ajustes de Bluetooth para el usuario, así:

Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); 
    startActivityForResult(intent, REQUEST_PAIR_DEVICE); 
9

que lograron petición de auto de un proceso de asociación con el teclado dispositivos destacados a través de una aplicación que funciona como un servicio que verifica la presencia de un tipo específico de dispositivo y una versión modificada de la aplicación Configuración.

Debo decir que estaba trabajando en un dispositivo personalizado con Android 4.0.3 sin controles externos (sin botones para retroceder/Inicio/confirmar): emparejar un controlador al arrancar sin interacción hasta que la solicitud PIN sea obligatoria.

Primero creó un servicio a partir de una actividad en el arranque (con android.intent.action.BOOT_COMPLETED y android.permission.RECEIVE_BOOT_COMPLETED) que comprueba periódicamente la presencia de un dispositivo de clase 1344 (un teclado, la única forma de datos de entrada a petición) en la devolución de llamada OnReceive:

public void onReceive(Context context, Intent intent) 
... 
    BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
... 
if(dev.getBluetoothClass().getDeviceClass() == 1344){...} 

Una vez filtrado puedo escoger al primer teclado disponibles y luego pasar la dirección BT para la aplicación Ajustes:

Intent btSettingsIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); 
btSettingsIntent.putExtra("btcontroller", dev.getAddress()); 
startActivityForResult(btSettingsIntent, 1); 

la parte difícil estaba buscando la mejor posición para llamar el proceso de emparejamiento. Utilizando sólo los

intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN); 

me llevó a un cuadro de diálogo de pelado que una vez cerrado me dejó con el dispositivo emparejado, pero inutilizable.

Excavando en las clases de com.Android.settings.Bluetooth he encontrado mi camino a través de la

createDevicePreference(CachedBluetoothDevice cachedDevice) 

en el DeviceListPreferenceFragment.

Desde allí se puede comparar mi dirección de BT seleccionada previamente con los que están disponibles por delante y una vez emparejado con éxito llamo

cachedDevice.startPairing(); 

Yo sé, es complicado y requiere acceso al código fuente de Android, pero en una costumbre entorno en el que funciona

Espero que esto pueda ser útil.

+0

no puede hacer que funcione, lo que sugirió ... –

+0

esto no responde a la pregunta – Caner

3

Usando la reflexión puede llamar al método createBond desde la clase BluetoothDevice.

ver este mensaje: How to unpair or delete paired bluetooth device programmatically on android?

También hay una solución para desvincular.

+1

... que se elimina desde JB aka 4.1.x – Ewoks

+2

No se ha eliminado, esto todavía funciona con mi 4.3 Nexus 4 y todavía está muy en el [código fuente] (http://grepcode.com/file/repository.grepcode.com/java/ext/com .google.android/android/ 4.3_r2.1/android/bluetooth/BluetoothDevice.java) – AJ87uk

0

estoy usando esta clase para hacer la conexión entre mi teléfono inteligente cliente y el dispositivo servidor:

private class ConnectThread extends Thread 
{ 
    private final BluetoothSocket mmSocket; 

    private final UUID WELL_KNOWN_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); 

    public ConnectThread(BluetoothDevice device) 
    { 
     // Use a temporary object that is later assigned to mmSocket,because 
     // mmSocket is final 
     BluetoothSocket tmp = null; 

     // Get a BluetoothSocket to connect with the given BluetoothDevice 
     try 
     { 
      tmp = device.createRfcommSocketToServiceRecord(WELL_KNOWN_UUID); 
      //This is the trick 
      Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); 
      tmp = (BluetoothSocket) m.invoke(device, 1); 
     } catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

     mmSocket = tmp; 
    } 

    public void run() 
    { 
     DebugLog.i(TAG, "Trying to connect..."); 
     // 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 
      mmSocket.connect(); 
      DebugLog.i(TAG, "Connection stablished"); 
     } catch (IOException connectException) 
     { 
      // Unable to connect; close the socket and get out 
      DebugLog.e(TAG, "Fail to connect!", connectException); 
      try 
      { 
       mmSocket.close(); 
      } catch (IOException closeException) 
      { 
       DebugLog.e(TAG, "Fail to close connection", closeException); 
      } 
      return; 
     } 
    } 

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

primer lugar, obtener el objeto BluetoothDevice que desea conectar (lista de dispositivos emparejados o dispositivos discoverying).A continuación, hacer:

ConnectThread ct = new ConnectThread(device); 
ct.start(); 

Debido connect() es una llamada de bloqueo, este procedimiento de conexión debe realizarse siempre en un hilo separado del hilo principal actividad. Consulte Android Developers para obtener información más detallada.

+0

Quiero implementar un dispositivo enviar imagen a otro dispositivo a través de bluetooth ... pero me quedé atrapado en Aceptar hilo ... ¿Qué hacer ...? ? –

+0

@Umang, mi respuesta es solo para emparejar dispositivos. La información de intercambio entre ellos es otra historia. Le sugiero que cree una publicación que detalle su problema. – DragonT

+0

puede ver esto: http://stackoverflow.com/questions/23648942/send-text-message-from-one-device-to-another-via-bluetooth-in-android –

-1

Esto es cómo lo consigo:

Bluetooth device = mBtAdapter.getRemoteDevice(address); 
//address:11:23:FF:cc:22 
Method m = device.getClass()   
.getMethod("createBond", (Class[]) null); 
     m.invoke(device, (Object[]) null); // send pairing dialog request 

After pairing// 
     connectDevice(address); 
2

La reflexión es de poco fiar, diferentes fabricantes pueden cambiar estos métodos subyacentes como deseen! He probado muchas aplicaciones diferentes en nuestros 10 dispositivos aquí y estos métodos de reflexión solo funcionan completamente en aproximadamente el 75% de los dispositivos. Si desea una aplicación que funcione para todos, tenga mucho cuidado al usar la función de reflexión: pruebe algunas pruebas en la nube para probar su aplicación en más de 100 dispositivos y verifique la tasa de fallas.

En este caso reflexión no se necesita en absoluto desde la API 19 (KitKat 4.4)

BluetoothDevice tiene nuevo método CreateBond.

private void pairDevice(BluetoothDevice device) { 

      device.createBond(); 
    } 

developer.android.com/reference/android/bluetooth/BluetoothDevice.html

+0

es posible probar bluetooth en la nube herramientas de prueba basadas? – Sapher

+1

No lo he visto recientemente, el año pasado lo intenté y ninguna empresa de pruebas en la nube que contacté me permitió hacer este tipo de prueba. –

4

Es mi respuesta:

en onCreate() hacer esto:

registerReceiver(incomingPairRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)); 

a continuación, crear variable

private final BroadcastReceiver incomingPairRequestReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 
     if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) { 
      BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      //pair from device: dev.getName() 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
       dev.setPairingConfirmation(true); 
       //successfull pairing 
      } else { 
       //impossible to automatically perform pairing, 
       //your Android version is below KITKAT 
      } 
     } 
    } 
}; 
+1

'setPairingConfirmation (boolean confirm)' necesita permiso BLUETOOTH_PRIVILEGED, pero este permiso no está disponible para aplicaciones de terceros. Ver [Desarrolladores de Android] (https://developer.android.com/reference/android/Manifest.permission.html#BLUETOOTH_PRIVILEGED) – Roses

Cuestiones relacionadas