scanner - mostrar dispositivos bluetooth en android studio
Cómo asociar programáticamente un dispositivo bluetooth en Android (10)
¡La reflexión es DODGY, diferentes fabricantes pueden cambiar estos métodos subyacentes como lo deseen! He probado muchas aplicaciones diferentes en nuestros 10 dispositivos aquí y este método de reflexión solo funciona completamente en aproximadamente el 75% de los dispositivos. Si desea una aplicación que funcione para todos, tenga mucho cuidado al usar Reflection: 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, la reflexión no es necesaria 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
Para mi aplicación estoy intentando emparejar un dispositivo bluetooth mediante programación. Puedo mostrar el diálogo de emparejamiento para el dispositivo que quiero emparejar y puedo ingresar un código PIN. Cuando presiono "Emparejar", el diálogo se elimina y no pasa nada.
Solo necesito soportar dispositivos con Android 2.0 y más nuevos.
Actualmente estoy usando el siguiente código para iniciar el progreso del emparejamiento:
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 sincronización, detengo la búsqueda de nuevos dispositivos.
Mi aplicación tiene los siguientes permisos de bluetooth:
- android.permission.BLUETOOTH_ADMIN
- android.permission.BLUETOOTH
Además de mi comentario, por cierto, incluso si estos tipos de ACCIÓN existieran, no es así como se usan. Aquí hay 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);
Así es como 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);
Desafortunadamente, creo que lo mejor que obtendrás es abrir Configuración / Conexiones inalámbricas y redes / Configuración de Bluetooth para el usuario como:
Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
startActivityForResult(intent, REQUEST_PAIR_DEVICE);
Descubrí que el uso de diferentes valores para PAIRING_VARIANT_PIN da como resultado diferentes comportamientos de UI de emparejamiento.
Consulte 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 emparejamiento debería dar como resultado que se muestre una clave de acceso de 6 dígitos en ambos dispositivos.
El mejor resultado que pude lograr fue usar PAIRING_VARIANT_PIN = 0. Cuando se lo solicité mi aplicación, ingresé el pin 1234 y apareció una clave de acceso de 6 dígitos en mi dispositivo de destino. La UI de emparejamiento terminó y eso fue todo.
O bien, debe averiguar cómo iniciar una solicitud de emparejamiento de Bluetooth 2.1, utilizando alguna otra variante de emparejamiento o pin de variante de emparejamiento. O bien, no está captando el resultado de la actividad que se está ejecutando correctamente.
Dada la cantidad de tiempo que he intentado hacer esto, decidí que mis usuarios finales solo tendrían que emparejarse con la configuración de Android antes de usar mi aplicación.
Es mi respuesta:
en onCreate () escribe esto:
registerReceiver(incomingPairRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
luego crea la 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
}
}
}
};
Estoy usando esta clase para hacer la conexión entre el teléfono inteligente de mi 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)
{
}
}
}
Primero, obtenga el objeto developer.android.com/reference/android/bluetooth/… que desea conectar (con una lista de dispositivos emparejados o dispositivos de descubrimiento). Entonces hazlo:
ConnectThread ct = new ConnectThread(device);
ct.start();
Debido a que connect() es una llamada de bloqueo, este procedimiento de conexión siempre debe realizarse en un hilo separado del hilo de actividad principal. Consulte Desarrolladores de Android para obtener información más detallada.
Logré solicitar automáticamente un procedimiento de emparejamiento con dispositivos con teclado 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 Atrás / Inicio / confirmar): emparejando un controlador en el arranque completo sin ninguna interacción hasta que la solicitud del PIN era obligatoria.
Primero creé un servicio que iniciaba una actividad en el arranque (con android.intent.action.BOOT_COMPLETED
y android.permission.RECEIVE_BOOT_COMPLETED)
que verifica periódicamente la presencia de un dispositivo de clase 1344 (un teclado, la única forma de ingresar datos a solicitud) 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, elijo el primer teclado disponible y luego paso la dirección de BT a la aplicación de configuración:
Intent btSettingsIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
btSettingsIntent.putExtra("btcontroller", dev.getAddress());
startActivityForResult(btSettingsIntent, 1);
La parte difícil fue buscar la mejor posición para llamar el proceso de emparejamiento. Usando solo el
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
me llevó a un diálogo de emparejamiento que una vez cerrado me dejó con el dispositivo emparejado, pero inutilizable.
Cavando en las clases de com.Android.settings.Bluetooth encontré mi camino a través de la
createDevicePreference(CachedBluetoothDevice cachedDevice)
en el DeviceListPreferenceFragment.
A partir de ahí comparé mi dirección de BT previamente seleccionada con las disponibles y una vez que coincidí, llamé
cachedDevice.startPairing();
Lo sé, es complicado y requiere acceso al código fuente de Android, pero en un entorno personalizado funciona.
Espero que esto pueda ser de ayuda.
Puede ser que necesites iniciarActivityForResult en lugar de solo startActivity?
Otra opción es buscar en el ejemplo de la aplicación BluetoothChat e iniciar un zócalo de conexión RFComm, tan pronto como inicie el zócalo, aparecerá automáticamente una solicitud de emparejamiento sin necesidad de enviar un intento diferente de emparejamiento. De esta manera no necesitarás manejar el emparejamiento.
http://developer.android.com/resources/samples/BluetoothChat/index.html
Usando la reflexión puede llamar al método createBond desde la clase BluetoothDevice.
Consulte esta publicación: ¿Cómo desemparejar o eliminar un dispositivo Bluetooth emparejado mediante programación en Android?
También hay una solución para desvincular.