Registrar el receptor de difusión dinámicamente no funciona – BluetoothDevice.ACTION_FOUND
El uso de la clase Log
para realizar el seguimiento de Runtime muestra que onReceive()
methode no se llama, ¿por qué?
Registrar el receptor de difusión dinámicamente
- ¿Es posible llamar al método onReceive desde un diálogo?
- Excepción de tiempo de ejecución Android O con boot_completed
- Instalar referrer no funciona en algunos dispositivos redmi
- Las transmisiones se retrasan
- Receptor de difusión no funciona después de reiniciar el dispositivo en Android
private void discoverDevices () { Log.e("MOHAB","BEFORE ON RECEIVE"); mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { Log.e("MOHAB","ON RECEIVE"); 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 Bluetooth b = new Bluetooth(device.getName(),device.getAddress()); list.add(b); } } }; Log.e("MOHAB","create intentFilter"); // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy }
- ¿Cómo comprobar si Receiver está registrado en Android?
- Boot BroadcastReceiver no funciona en los dispositivos Xiaomi
- Cómo saber si la emisión recibió Android
- Android - "El receptor exportado no requiere permiso" en receptores destinados a recibir de los servicios del sistema
- Maneje los cambios de red en android 7 Turrón
- Cargador de difusión desconectado en Android O
- Transmisión local desde Servicio no recibido por Actividad
- ¿Qué contexto recibe BroadcastReceivers al escuchar BOOT_COMPLETED?
Lo que te perdiste es que necesitas iniciar una recuperación de dispositivos
En primer lugar, obtener el adaptador bluetooth
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Después de eso, inicia el descubrimiento llamando al
mBtAdapter.startDiscovery();
También debe leer los detalles aquí, por ejemplo, acerca de cancelDiscovery()
http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery%28%29
PS También, se sugiere utilizar context.getSystemService(Context.BLUETOOTH_SERVICE)
para obtener el BluetoothAdapter en API 18+, según el documento oficial.
Para obtener un BluetoothAdapter que representa el adaptador Bluetooth local, al ejecutar JELLY_BEAN_MR1 y posteriormente, llame al método estático getDefaultAdapter (); Cuando se ejecuta en JELLY_BEAN_MR2 y superior, recupérelo a través de getSystemService (Class) con BLUETOOTH_SERVICE.
Edit: Recuerda que necesitas el permiso de BLUETOOTH_ADMIN para startDiscovery()
Aparte del hecho de que a partir de Android 6.0 debes tener el permiso ACCESS_COARSE_LOCATION
para recibir ACTION_FOUND
(como @siniux ya se ha mencionado), hay otra cosa relacionada:
ACCESS_COARSE_LOCATION
está entre los permisos peligrosos que tiene que solicitar explícitamente del usuario en tiempo de ejecución (otra mejora de seguridad incluida en 6.0).
Para diagnosticar, puede ejecutar adb logcat | grep BroadcastQueue
adb logcat | grep BroadcastQueue
, y ver algo como esto:
W/BroadcastQueue: Permission Denial: receiving Intent { act=android.bluetooth.device.action.FOUND flg=0x10 (has extras) } to ProcessRecord{9007:com.examplepackage} (pid=9007, uid=10492) requires android.permission.ACCESS_COARSE_LOCATION due to sender com.android.bluetooth (uid 1002)
Por lo tanto, el procedimiento correcto para el descubrimiento de dispositivos BT en Marshmallow es el siguiente:
-
Tener el requisito de permiso
ACCESS_COARSE_LOCATION
en el manifiesto junto con los permisos habituales de bluetooth:<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-
Asegúrese de tener permiso de tiempo de ejecución para
ACCESS_COARSE_LOCATION
protected void checkLocationPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_COARSE_LOCATION); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_COARSE_LOCATION: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { proceedDiscovery(); // ---> } else { //TODO re-request } break; } }
}
-
Registre un receptor de difusión para
ACTION_FOUND
y llame aBluetoothAdapter.startDiscovery()
protected void proceedDiscovery() { IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED); registerReceiver(mReceiver, filter); mBluetoothAdapter.startDiscovery(); }
Lo curioso de ACTION_NAME_CHANGED
. Aunque 6.0 no te entregará ACTION_FOUND
sin el permiso de ubicación aproximada, ACTION_NAME_CHANGED
eventos de ACTION_NAME_CHANGED
, que normalmente se ACTION_FOUND
con ACTION_FOUND
cuando se descubren los dispositivos. Es decir, obtienes los dos eventos, así que sin el permiso, puedes manejar ACTION_NAME_CHANGED
para prácticamente el mismo comportamiento. (Los gurús, me corrigen si estoy equivocado)
Yo estaba teniendo un problema similar con un receptor de difusión. Entonces encontré esto: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id
Básicamente, en 6.0 debe utilizar el permiso de ubicación para buscar dispositivos Bluetooth.
No sé si su código es correcto en conseguir el dispositivo bluetooth. Aquí es lo que siento acerca de su código es. Intializar y registrar BroadcastReceiver dentro de una función es una mala idea. Debe hacerlo fuera del método onCreate()
. Aquí está la cosa que usted necesita hacer en su código
Como sobre el registro de Reciver que tiene que hacerse en onCreate()
como este
registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
Siguientes con inicialización o reciever
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e("MOHAB","ON RECEIVE"); 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 Bluetooth b = new Bluetooth(device.getName(),device.getAddress()); list.add(b); } } };
Unregister reciver in onPause()
no olvides que
Y en su discoverDevices()
acaba de devolver la list
de dispositivos añadidos por el reciver para cada llamada de esa fumación;
Publicar esto como una respuesta, como no puedo comentar con mi actual nivel de representante.
¿Tiene la permisson Bluetooth incluida en AndroidManifest.xml?
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Si no, intente (y la investigación) cada uno por separado, ya que no recuerdo la importancia de cada uno.
Si usted tiene estos, por favor incluya más de su código, por lo que será posible diagnosticar su problema.
- DoInBackground () error en facebook api en android studio
- Buscando una clase de fragmento errónea con la biblioteca de compatibilidad de Android