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

  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 } 

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:

  1. 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" /> 
  2. 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; } } 

    }

  3. Registre un receptor de difusión para ACTION_FOUND y llame a BluetoothAdapter.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.

  • Cómo manejar la notificación de Fire Base cuando la aplicación está en primer plano
  • Recibir notificación de análisis mediante el receptor de difusión personalizado
  • Crash while self update APK (la clase de componente no existe)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.