Ble scanning callback only get called several times then stopped

前端 未结 2 1341
终归单人心
终归单人心 2020-12-15 10:54

I have 2 phones with Android 5.0.2, they both installed the latest Radius Beacon\'s App: Locate Beacon, meanwhile, I turned on 2 IBeacon sender, and can see

2条回答
  •  伪装坚强ぢ
    2020-12-15 11:28

    David - Are you sure that scan callback gets called for every non-connectable advertisement. I have a Xiaomi Redmi 3 and another Nexus 5 phone running Android 6.0. I have a BLE sensor that at every 1 minute interval sends the data. These phones appearing as central BLE device should receive and process the data from the sensor. I can see from an Over the Air (OTA) BLE capture device that it the sensor is sending data every 1 minute. However both phones seems to process data for few minutes at 1 minute interval but after that stop processing for 4 - 6 minutes and then start processing agenter code hereain. Time interval of phone processing on looks like this 1 min, 2 min, 3 min, 8min, 9min, 10min, 11 min So after processing 3 packets at 1 minute interval, either phone will stop processing for 4 -6 minutes.

    Here is code that does the processing.

    public class BluetoothDataReader {
        private final Context context;
    
        public BluetoothDataReader(Context context) {
            this.context = context;
        }
    
        public void startReading() {
            BluetoothAdapter btAdapter = getBluetoothAdapter();
            if (btAdapter == null) return;
    
            BluetoothLeScanner scanner = btAdapter.getBluetoothLeScanner();
            ScanSettings settings = new ScanSettings.Builder()
                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                    .build();
            scanner.startScan(Collections.emptyList(), settings, new ScanRecordReader());
        }
    
        public void uploadScanBytes(SensorDataUploader sensorDataUploader, int count) {
            BluetoothAdapter btAdapter = getBluetoothAdapter();
            if (btAdapter == null) return;
    
            BluetoothLeScanner scanner = btAdapter.getBluetoothLeScanner();
            ScanSettings settings = new ScanSettings.Builder()
                    .setScanMode(ScanSettings.SCAN_MODE_BALANCED)
                    .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                    .build();
     //       scanner.startScan(Arrays.asList(new ScanFilter.Builder().setDeviceAddress("26:50:26:50:26:50").build()), settings, new LimitedScanRecordReader(sensorDataUploader, count, scanner));
               scanner.startScan(Collections.emptyList(), settings, new LimitedScanRecordReader(sensorDataUploader, count, scanner));
        }
    
        @Nullable
        private BluetoothAdapter getBluetoothAdapter() {
            BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
            if(btAdapter == null){
                Log.i(BluetoothDataReader.class.getName(), "No bluetooth adapter available");
                return null;
            }
    
            if(!btAdapter.isEnabled()){
                Log.i(BluetoothDataReader.class.getName(), "Enable bluetooth adapter");
                Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                context.startActivity(enableBluetooth);
            }
            return btAdapter;
        }
    
        private class LimitedScanRecordReader extends ScanCallback {
            private final int limit;
            private final BluetoothLeScanner scanner;
    
    
            private int scanRecordRead = 0;
            private final SensorDataUploader sensorDataUploader;
    
            private LimitedScanRecordReader( SensorDataUploader sensorDataUploader, int limit, BluetoothLeScanner scanner) {
                this.limit = limit;
                this.scanner = scanner;
                this.sensorDataUploader = sensorDataUploader;
            }
    
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
    //            if(scanRecordRead++ < limit) {
       //         if(result.getDevice().getAddress().equals("A0:E6:F8:01:02:03")) {
       //         if(result.getDevice().getAddress().equals("C0:97:27:2B:74:D5")) {
    
                if(result.getDevice().getAddress().equals("A0:E6:F8:01:02:03")) {
                    long timestamp = System.currentTimeMillis() -
                            SystemClock.elapsedRealtime() +
                            result.getTimestampNanos() / 1000000;
    
    
    
                    byte[] rawBytes = result.getScanRecord().getBytes();
                    Log.i(DataTransferService.class.getName(), "Raw bytes: " + byteArrayToHex(rawBytes));
                    sensorDataUploader.upload(timestamp, rawBytes);
                }
    //            }else {
    //                scanner.stopScan(this);
    //            }
            }
            public String byteArrayToHex(byte[] a) {
                StringBuilder sb = new StringBuilder(a.length * 2);
                for(byte b: a)
                    sb.append(String.format("%02x", b & 0xff));
                return sb.toString();
            }
    
            public void onScanFailed(int errorCode) {
                Log.i(DataTransferService.class.getName(), "Error code is:" + errorCode);
            }
    
            public void onBatchScanResults(java.util.List results) {
                Log.i(DataTransferService.class.getName(), "Batch scan results");
            }
        }
    
        private class ScanRecordReader extends ScanCallback {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                byte []rawBytes = result.getScanRecord().getBytes();
                Log.i(DataTransferService.class.getName(), "Raw bytes: " + byteArrayToHex(rawBytes ));
    //            Map serviceData = result.getScanRecord().getServiceData();
    //            for(ParcelUuid uuid : serviceData.keySet()) {
    //                Log.i(DataTransferService.class.getName(), uuid.toString() + ":" +  byteArrayToHex(serviceData.get(uuid)));
    //            }
    //            Log.i(DataTransferService.class.getName(),result.toString());
            }
            public String byteArrayToHex(byte[] a) {
                StringBuilder sb = new StringBuilder(a.length * 2);
                for(byte b: a)
                    sb.append(String.format("%02x", b & 0xff));
                return sb.toString();
            }
    
            public void onScanFailed(int errorCode) {
                Log.i(DataTransferService.class.getName(), "Error code is:" + errorCode);
            }
    
            public void onBatchScanResults(java.util.List results) {
                Log.i(DataTransferService.class.getName(), "Batch scan results");
            }
        }
    }
    

提交回复
热议问题