Android BLE- ¿Cómo se llama al método onScanResult en ScanCallback?

Esta es mi primera vez haciendo Bluetooth Low Energy en el proyecto Android. El proyecto que estoy haciendo es básicamente detectar todos los dispositivos Bluetooth LE y conectarlos para descubrir sus servicios.

Me gustaría preguntar si alguien sabe cómo se están llamando los métodos onScanResult (), onBatchScanResults () y onScanFailed () en ScanCallback?

En Primero, ejecute el método scanLeDevice ().

BluetoothLeScanner mLEScanner = mBluetoothAdapter.getBluetoothLeScanner(); ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .build(); List<ScanFilter> filters = new ArrayList<ScanFilter>(); scanLeDevice(true); 

En este método, se iniciaráScan. Asumo que los resultados de la exploración se entregan usando estas devolución de llamada.

 @TargetApi(21) private void scanLeDevice(final boolean enable) { if (enable) { //stops scanning after a pre-defined scan period mHandler.postDelayed(new Runnable() { @Override public void run() { System.out.println("BLE// mLEScanner.stopScan(mScanCallback) "); mLEScanner.stopScan(mScanCallback); } } }, SCAN_PERIOD); System.out.println("BLE// mLEScanner.startScan(filters, settings, mScanCallback)"); mLEScanner.startScan(filters, settings, mScanCallback); } else { System.out.println("BLE// mLEScanner.stopScan(mScanCallback)"); mLEScanner.stopScan(mScanCallback); } } 

Sin embargo, en ScanCallback, no tengo ni idea de cómo desencadena onScanResult y entregar el resultado de análisis utilizando la devolución de llamada. En mis pruebas (como se muestra a continuación), ni onScanResult () ni onBatchScanResults () y onScanFailed () serán llamados. ¿Puede alguien explicarme el concepto? ¡Me ayudará mucho!

  /* Scan result for SDK >= 21 */ private ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { System.out.println("BLE// onScanResult"); Log.i("callbackType", String.valueOf(callbackType)); Log.i("result", result.toString()); BluetoothDevice btDevice = result.getDevice(); connectToDevice(btDevice); } @Override public void onBatchScanResults(List<ScanResult> results) { System.out.println("BLE// onBatchScanResults"); for (ScanResult sr : results) { Log.i("ScanResult - Results", sr.toString()); } } @Override public void onScanFailed(int errorCode) { System.out.println("BLE// onScanFailed"); Log.e("Scan Failed", "Error Code: " + errorCode); } }; 

 02-17 10:38:38.513 878-895/? D/BluetoothManagerService: Added callback: android.bluetooth.IBluetoothManagerCallback$Stub$Proxy@8334cf4:true 02-17 10:38:38.520 782-782/? D/BluetoothAdapter: STATE_ON 02-17 10:38:38.529 21554-21590/? D/BtGatt.GattService: registerClient() - UUID=835342c6-81eb-4e09-9729-5bbe1c22bc86 02-17 10:38:38.529 21554-21570/? D/BtGatt.GattService: onClientRegistered() - UUID=835342c6-81eb-4e09-9729-5bbe1c22bc86, clientIf=5 02-17 10:38:38.530 782-793/? D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5 02-17 10:38:38.530 21554-21599/? D/BtGatt.GattService: start scan with filters 02-17 10:38:38.532 782-782/? I/System.out: BLE// mLEScanner.startScan(filters, settings, mScanCallback) 02-17 10:38:38.532 21554-21573/? D/BtGatt.ScanManager: handling starting scan 02-17 10:38:38.534 21576-21577/? I/WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl() 02-17 10:38:38.542 21554-21570/? D/BtGatt.GattService: onScanFilterEnableDisabled() - clientIf=5, status=0, action=1 02-17 10:38:38.543 21554-21570/? D/BtGatt.ScanManager: callback done for clientIf - 5 status - 0 02-17 10:38:38.543 21554-21573/? D/BtGatt.ScanManager: configureFilterParamter 500 10000 1 0 02-17 10:38:38.547 21554-21570/? D/BtGatt.GattService: onScanFilterParamsConfigured() - clientIf=5, status=0, action=0, availableSpace=15 02-17 10:38:38.547 21554-21570/? D/BtGatt.ScanManager: callback done for clientIf - 5 status - 0 02-17 10:38:38.548 21554-21573/? D/BtGatt.ScanManager: configureRegularScanParams() - queue=1 02-17 10:38:38.548 487-2827/? I/ACDB-LOADER: ACDB AFE returned = -19 02-17 10:38:38.549 21554-21573/? D/BtGatt.ScanManager: configureRegularScanParams() - ScanSetting Scan mode=0 mLastConfiguredScanSetting=-2147483648 02-17 10:38:38.549 21554-21573/? D/BtGatt.ScanManager: configureRegularScanParams - scanInterval = 8000configureRegularScanParams - scanWindow = 800 02-17 10:38:38.549 21554-21570/? D/BtGatt.GattService: onScanParamSetupCompleted : 0 02-17 10:38:38.568 21554-21574/? W/bt_hci: filter_incoming_event command complete event with no matching command. opcode: 0x0. 02-17 10:38:38.603 21554-21570/? D/bt_btif_gattc: btif_gattc_update_properties BLE device name=Polar HR Sensor len=15 dev_type=2 02-17 10:38:39.571 21576-21585/? I/WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl() 02-17 10:38:43.526 782-782/? I/System.out: BLE// mLEScanner.stopScan(mScanCallback) 02-17 10:38:43.599 21576-21576/? I/WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK ON using UART driver's ioctl() 02-17 10:38:43.967 21576-21576/? I/WCNSS_FILTER: ibs_msm_serial_clock_vote: vote UART CLK OFF using UART driver's ioctl() 

Uso del teléfono Android con API 23

El código que he escrito aquí se refiere a: http://www.truiton.com/2015/04/android-bluetooth-low-energy-ble-example/



[Código actualizado V1] – No funciona

Aquí está todo mi código que he creado un periférico virtual y está en modo de publicidad. El Periférico virtual se crea a través de una aplicación llamada LightBlue: https://itunes.apple.com/us/app/lightblue-explorer-bluetooth/id557428110?mt=8 Por favor, ayúdame a revisar mi código 🙂

 @TargetApi(21) public class BluetoothLE extends Fragment { View view; private BluetoothAdapter mBluetoothAdapter; private int REQUEST_ENABLE_BT = 1; private Handler mHandler; private static final long SCAN_PERIOD = 5000; // Stops scanning after 5 seconds private BluetoothLeScanner mLEScanner; private BluetoothGatt mGatt; //To provide bluetooth communication private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1; private int permissionCheck; public BluetoothLE(){ //empty constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment view = inflater.inflate(R.layout.fragment_bluetooth, container, false); mHandler = new Handler(); /* check if BLE is supported in this phone */ if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(getActivity(), "BLE Not Supported", Toast.LENGTH_SHORT).show(); getActivity().finish(); } /* Enable bluetooth without leaving app */ final BluetoothManager bluetoothManager = (BluetoothManager) getActivity().getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); /* Build ScanSetting */ ScanSettings.Builder scanSetting = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) .setReportDelay(5000); settings = scanSetting.build(); return view; } @TargetApi(Build.VERSION_CODES.M) @Override public void onResume() { super.onResume(); /* Ensures Bluetooth is available on the device and it is enabled. If not, displays a dialog requesting user permission to enable Bluetooth. */ if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { //Unable to obtain a BluetoothAdapter Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); //trigger onActivityResult } else { if (Build.VERSION.SDK_INT >= 21) { mLEScanner = mBluetoothAdapter.getBluetoothLeScanner(); settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .build(); filters = new ArrayList<ScanFilter>(); } if(Build.VERSION.SDK_INT >= 23){ checkLocationPermission(); } scanLeDevice(true); } } @Override public void onPause() { super.onPause(); if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { scanLeDevice(false); } } @Override public void onDestroy() { if (mGatt == null) { return; } mGatt.close(); mGatt = null; super.onDestroy(); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { System.out.println("BLE// onActivityResult"); if (requestCode == REQUEST_ENABLE_BT) { if (resultCode == Activity.RESULT_CANCELED) { //Bluetooth not enabled. getActivity().finish(); return; } } super.onActivityResult(requestCode, resultCode, data); } private void scanLeDevice(final boolean enable) { if (enable) { //stops scanning after a pre-defined scan period mHandler.postDelayed(new Runnable() { @Override public void run() { if (Build.VERSION.SDK_INT < 21) { System.out.println("BLE// mBluetoothAdapter.stopLeScan(mLeScanCallback) "); mBluetoothAdapter.stopLeScan(mLeScanCallback); } else { mLEScanner.stopScan(mScanCallback); System.out.println("BLE// mLEScanner.stopScan(mScanCallback) "); } } }, SCAN_PERIOD); if (Build.VERSION.SDK_INT < 21) { System.out.println("BLE// mBluetoothAdapter.startLeScan(mLeScanCallback)"); mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mLEScanner.startScan(mScanCallback); //mLEScanner.startScan(filters, settings, mScanCallback); System.out.println("BLE// mLEScanner.startScan(mScanCallback) "); } } else { if (Build.VERSION.SDK_INT < 21) { System.out.println("BLE// mBluetoothAdapter.stopLeScan(mLeScanCallback)"); mBluetoothAdapter.stopLeScan(mLeScanCallback); } else { System.out.println("BLE// mLEScanner.stopScan(mScanCallback)"); mLEScanner.stopScan(mScanCallback); } } } /* Scan result for SDK >= 21 */ private ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { System.out.println("BLE// onScanResult"); super.onScanResult(callbackType, result); Log.i("callbackType", String.valueOf(callbackType)); Log.i("result", result.toString()); Log.i("Device Name: ", result.getDevice().getName()); System.out.println("Signal: " + result.getRssi()); BluetoothDevice btDevice = result.getDevice(); connectToDevice(btDevice); } @Override public void onBatchScanResults(List<ScanResult> results) { System.out.println("BLE// onBatchScanResults"); for (ScanResult sr : results) { Log.i("ScanResult - Results", sr.toString()); } } @Override public void onScanFailed(int errorCode) { System.out.println("BLE// onScanFailed"); Log.e("Scan Failed", "Error Code: " + errorCode); } }; // scan results are returned here SDK < 21 private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { System.out.println("BLE// DEVICDE FOUND"); Log.i("onLeScan", device.toString()); connectToDevice(device); } }); } }; public void connectToDevice(BluetoothDevice device) { System.out.println("BLE// connectToDevice()"); if (mGatt == null) { mGatt = device.connectGatt(getActivity(), false, gattCallback); //Connect to a GATT Server //scanLeDevice(false);// will stop after first device detection } } private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { System.out.println("BLE// BluetoothGattCallback"); Log.i("onConnectionStateChange", "Status: " + status); switch (newState) { case BluetoothProfile.STATE_CONNECTED: Log.i("gattCallback", "STATE_CONNECTED"); gatt.discoverServices(); break; case BluetoothProfile.STATE_CONNECTING: Log.i("gattCallback", "STATE_CONNECTING"); break; case BluetoothProfile.STATE_DISCONNECTED: Log.e("gattCallback", "STATE_DISCONNECTED"); break; default: Log.e("gattCallback", "STATE_OTHER"); } } @Override //New services discovered public void onServicesDiscovered(BluetoothGatt gatt, int status) { List<BluetoothGattService> services = gatt.getServices(); Log.i("onServicesDiscovered", services.toString()); gatt.readCharacteristic(services.get(1).getCharacteristics().get (0)); } @Override //Result of a characteristic read operation public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { Log.i("onCharacteristicRead", characteristic.toString()); gatt.disconnect(); } }; public void checkLocationPermission(){ permissionCheck = ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION); switch(permissionCheck){ case PackageManager.PERMISSION_GRANTED: break; case PackageManager.PERMISSION_DENIED: if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION)){ //Show an explanation to user *asynchronouselly* -- don't block //this thread waiting for the user's response! After user sees the explanation, try again to request the permission Snackbar.make(view, "Location access is required to show Bluetooth devices nearby.", Snackbar.LENGTH_LONG).setAction("Action", null).show(); } else{ //No explanation needed, we can request the permission ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION); } break; } } } 

2 Solutions collect form web for “Android BLE- ¿Cómo se llama al método onScanResult en ScanCallback?”

Veo que está utilizando el método public void startScan (List<ScanFilter> filters, ScanSettings settings, ScanCallback callback) de startScan() , pero nunca define ningún filtro. En su lugar, pasa una ArrayList vacía de ScanFilters. Por lo tanto, nunca recibirá ninguna devolución de llamada porque no se proporciona ningún criterio para que los filtros coincidan.

Dado que usted dijo que desea buscar todos los dispositivos BLE, no hay necesidad de utilizar ningún filtro en absoluto. En su lugar, utilice el método simple public void startScan (ScanCallback callback) , que no utiliza ningún filtro ni configuración especializada.

En cuanto a su solicitud para entender cómo funciona todo – Creo que tiene el concepto de base sobre la base de su código y su expectativa de que las devoluciones de llamada debe obtener activado. Inicia el análisis y el sistema se apaga y realiza el análisis sin bloquear la ejecución del código (es decir, lo hace de forma asíncrona). Mientras se está realizando la exploración, llamará a uno de los tres métodos del objeto de devolución de llamada siempre que sea necesario (como se describe en la documentación de la API). Eso es practicamente todo.

ACTUALIZACIÓN : Asegúrese de que solicita los permisos BLUETOOTH, BLUETOOTH_ADMIN, así como los permisos ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION. Estos son necesarios para recibir devoluciones de llamada desde el método startScan() . Desafortunadamente, si usted no solicita esos persmissions, el escaneo apenas falla silenciosamente. Preferiría si el sistema proporciona un mensaje de advertencia en los registros o activa una devolución de llamada al método onScanFailed() con el onScanFailed() indica el problema.

Así que … finalmente encontré la respuesta. Para dispositivos Android que son Android 6.0 o superior (como mi teléfono es Nexus 5x), ambos GPS y Bluetooth en la configuración del teléfono debe activarse, además de su manifiesto debe agregar BLUETOOTH BLUETOOTH_ADMIN ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION permiso.

Ahora todo funciona bien para mí 🙂

  • ¿Qué es "escritura confiable" en BLE?
  • ¿Funciona BluetoothLeAdvertiser en un Nexus 5 con Android 5.0?
  • Dispositivos con Android 4.2 (Jelly Bean) compatible con Bluetooth de baja energía (BLE)
  • Android BLE: onCharacteristicRead () parece estar bloqueado por subprocesos
  • Android Ble desconexión de tiempo
  • ¿Podemos convertir nuestro dispositivo Android en un faro?
  • OnServicesDiscovered es 129 y se conecta inestable para BLE en Android
  • Escanear el módulo ble (bluetooth 4.0) en el android studio
  • Android BLE: onCharacteristicChanged nunca se dispara
  • ¿Cómo usar LeDeviceListAdapter al intentar encontrar dispositivos BLE?
  • Cómo conectar un dispositivo Android a un dispositivo iOS a través de BLE (Bluetooth Low Energy)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.