NordicSemiconductor / Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
BSD 3-Clause "New" or "Revised" License
1.98k stars 413 forks source link

Sometimes causing system Bluetooth to crash. #556

Open Fly-Felix opened 4 months ago

Fly-Felix commented 4 months ago

This happens when switching connections between multiple heartbeat devices. Please help me take a look, thank you!

I'm using implementation("no.nordicsemi.android:ble:2.7.4")

This is my error log:

2024-04-18 10:50:02.891 BluetoothGatt         D  connect() - device: CC:0A:BE:C2:DF:30, auto: false
2024-04-18 10:50:02.891 BluetoothGatt         D  registerApp()
2024-04-18 10:50:02.891 BluetoothGatt         D  registerApp() - UUID=272f563e-e11d-49b3-b01b-b61a094a7938
2024-04-18 10:50:02.894 BluetoothGatt         D  onClientRegistered() - status=0 clientIf=5
2024-04-18 10:50:03.311 BluetoothGatt         D  onClientConnectionState() - status=133 clientIf=5 device=CC:0A:BE:C2:DF:30
2024-04-18 10:50:03.313 HRGattService         W  Error: (0x85): GATT ERROR
2024-04-18 10:50:03.631 BluetoothGatt         D  onClientConnectionState() - status=0 clientIf=5 device=CC:0A:BE:C2:DF:30
2024-04-18 10:50:03.632 HRGattService         I  Connected to CC:0A:BE:C2:DF:30
2024-04-18 10:50:03.941 BluetoothGatt         D  onConnectionUpdated() - Device=CC:0A:BE:C2:DF:30 interval=6 latency=0 timeout=500 status=0
2024-04-18 10:50:03.943 HRGattService         I  Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
2024-04-18 10:50:04.750 BluetoothGatt         D  onConnectionUpdated() - Device=CC:0A:BE:C2:DF:30 interval=36 latency=0 timeout=500 status=0
2024-04-18 10:50:04.750 HRGattService         I  Connection parameters updated (interval: 45.0ms, latency: 0, timeout: 5000ms)
2024-04-18 10:50:05.638 BluetoothGatt         D  discoverServices() - device: CC:0A:BE:C2:DF:30
2024-04-18 10:50:05.652 BluetoothGatt         D  onSearchComplete() = Device=CC:0A:BE:C2:DF:30 Status=0
2024-04-18 10:50:05.696 HRGattService         I  Services discovered
2024-04-18 10:50:05.714 BluetoothGatt         D  setCharacteristicNotification() - uuid: 00002a37-0000-1000-8000-00805f9b34fb enable: true
2024-04-18 10:50:06.670 Bluetooth...Fragment  E  startScan: ---
2024-04-18 10:50:06.671 BluetoothManager      D  getConnectedDevices
2024-04-18 10:50:06.688 BluetoothAdapter      D  isLeEnabled(): ON
2024-04-18 10:50:06.693 BluetoothLeScanner    D  onScannerRegistered() - status=0 scannerId=6 mScannerId=0
2024-04-18 10:50:07.014 HRGattService         I  Data written to descr. 00002902-0000-1000-8000-00805f9b34fb
2024-04-18 10:50:07.015 HRGattService         I  Notifications enabled
2024-04-18 10:50:07.548 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:08.531 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:08.818 BluetoothGatt         D  onConnectionUpdated() - Device=CC:0A:BE:C2:DF:30 interval=24 latency=0 timeout=400 status=0
2024-04-18 10:50:08.819 HRGattService         I  Connection parameters updated (interval: 30.0ms, latency: 0, timeout: 4000ms)
2024-04-18 10:50:09.542 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:10.624 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:11.609 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:11.685 Bluetooth...Fragment  D  onBatchScanResults: ---1
2024-04-18 10:50:12.630 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:13.589 HRGattService         I  Notification received from 00002a37-0000-1000-8000-00805f9b34fb, value: (0x) 16-3C-E8-03
2024-04-18 10:50:16.703 Bluetooth...Fragment  D  onBatchScanResults: ---1
2024-04-18 10:50:21.707 Bluetooth...Fragment  D  onBatchScanResults: ---0
2024-04-18 10:50:26.699 Bluetooth...Fragment  E  stopScan: ---
2024-04-18 10:50:26.710 BluetoothAdapter      D  isLeEnabled(): ON
2024-04-18 10:50:30.247 ViewRootI...ctivity]  D  hardware acceleration = true , fakeHwAccelerated = false, sRendererDisabled = false, forceHwAccelerated = false, sSystemRendererDisabled = false
2024-04-18 10:50:30.328 Surface               D  Surface::connect(this=0x93877800,api=1)
2024-04-18 10:50:30.328 Surface               D  Surface::allocateBuffers(this=0x93877800)
2024-04-18 10:50:30.962 Surface               D  Surface::disconnect(this=0x93877800,api=1)
2024-04-18 10:50:30.967 OpenGLRenderer        D  endAllActiveAnimators on 0x936d5400 (RippleDrawable) with handle 0x936a64e0
2024-04-18 10:50:30.968 View                  D  [Warning] assignParent to null: this = DecorView@7e96f2d[BikeActivity]
2024-04-18 10:50:30.982 BluetoothGatt         D  cancelOpen() - device: CC:0A:BE:C2:DF:30
2024-04-18 10:50:30.989 BluetoothGatt         D  onClientConnectionState() - status=0 clientIf=5 device=CC:0A:BE:C2:DF:30
2024-04-18 10:50:31.010 HRGattService         I  Disconnected
2024-04-18 10:50:31.013 BluetoothGatt         D  close()
2024-04-18 10:50:31.013 BluetoothGatt         D  unregisterApp() - mClientIf=5
2024-04-18 10:50:34.543 ViewRootI...ctivity]  D  hardware acceleration = true , fakeHwAccelerated = false, sRendererDisabled = false, forceHwAccelerated = false, sSystemRendererDisabled = false
2024-04-18 10:50:34.608 Surface               D  Surface::allocateBuffers(this=0x93877800)
2024-04-18 10:50:34.608 Surface               D  Surface::connect(this=0x93877800,api=1)
2024-04-18 10:50:35.354 Surface               D  Surface::disconnect(this=0x93877800,api=1)
2024-04-18 10:50:35.355 OpenGLRenderer        D  endAllActiveAnimators on 0x8e488400 (RippleDrawable) with handle 0x8e4fe160
2024-04-18 10:50:35.355 View                  D  [Warning] assignParent to null: this = DecorView@9115c2f[BikeActivity]
2024-04-18 10:50:35.372 BluetoothGatt         D  connect() - device: EB:1D:23:A0:79:CF, auto: false
2024-04-18 10:50:35.372 BluetoothGatt         D  registerApp()
2024-04-18 10:50:35.373 BluetoothGatt         D  registerApp() - UUID=ce14f583-660a-4e2b-bc57-728b4e7a2bf5
2024-04-18 10:50:35.380 BluetoothGatt         D  onClientRegistered() - status=0 clientIf=5
2024-04-18 10:50:49.862 BluetoothAdapter      D  onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@12d2bc5
2024-04-18 10:50:49.913 BluetoothAdapter      D  onBluetoothServiceDown: null
2024-04-18 10:50:49.934 HRGattService         W  Connection attempt timed out
2024-04-18 10:50:49.939 BluetoothGatt         D  close()
2024-04-18 10:50:49.939 BluetoothGatt         D  unregisterApp() - mClientIf=5
2024-04-18 10:50:49.943 BluetoothGatt         E  
                                                 android.os.DeadObjectException
                                                    at android.os.BinderProxy.transactNative(Native Method)
                                                    at android.os.BinderProxy.transact(Binder.java:1129)
                                                    at android.bluetooth.IBluetoothGatt$Stub$Proxy.unregisterClient(IBluetoothGatt.java:1330)
                                                    at android.bluetooth.BluetoothGatt.unregisterApp(BluetoothGatt.java:819)
                                                    at android.bluetooth.BluetoothGatt.close(BluetoothGatt.java:705)
                                                    at no.nordicsemi.android.ble.BleManagerHandler.close(BleManagerHandler.java:536)
                                                    at no.nordicsemi.android.ble.BleManagerHandler.notifyDeviceDisconnected(BleManagerHandler.java:1932)
                                                    at no.nordicsemi.android.ble.BleManagerHandler$1.onReceive(BleManagerHandler.java:292)
                                                    at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1391)
                                                    at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
                                                    at android.os.Handler.handleCallback(Handler.java:873)
                                                    at android.os.Handler.dispatchMessage(Handler.java:99)
                                                    at android.os.Looper.loop(Looper.java:193)
                                                    at android.app.ActivityThread.main(ActivityThread.java:6702)
                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
2024-04-18 10:50:50.323 BluetoothAdapter      D  onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@fb9bf41

9a11d936a30d833ee152fc20388b61d

Fly-Felix commented 4 months ago

This is how I switch connections. Don't know what's the problem? Timeouts can easily occur after switching connections multiple times. Then the above problems will occur.

    private ConnectRequest connectRequest;

    private void addDevice(BluetoothDevice device) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (clientManager.isConnected()) {
                    try {
                        clientManager.disconnect().await();
                        clientManager.close();
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (connectRequest != null) {
                    connectRequest.cancel();
                }
                connectRequest = clientManager.connect(device)
                        .useAutoConnect(true)
                        .retry(3, 0)
                        .timeout(20 * 1000);
                connectRequest.enqueue();
            }
        }).start();
    }
Fly-Felix commented 4 months ago

Sorry, let me correct the description above. This error does not necessarily occur when the connection times out, because I just tested it and this error also occurs when the connection is in progress, and you can always see it when there is a problem.

2024-04-18 11:32:39.998 BluetoothAdapter D onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@9c53240
2024-04-18 11:32:40.021 BluetoothAdapter D onBluetoothServiceDown: null
Fly-Felix commented 4 months ago

So far I have tested 100% of the steps that trigger the problem. Triggering a rescan after connecting to the device or during the connection process can cause the above issues.

Fly-Felix commented 4 months ago

This is my scanning code. Currently, this kind of thing only happens on some Android 9.0 devices. I tested another Android 7.0 device. It was connecting or connected. It was normal when I rescanned it. With my scan settings, it might be possible. does it matter?

private void startScan() {
        if (!PermissionUtils.isGpsEnabled(requireContext())) {
            showGpsRequestReasonDialog();
            return;
        }
        Log.e(TAG, "startScan: ---");

        binding.mSrLayout.setRefreshing(true);
        mDeviceAdapter.setNewData(getConnectedDevices());

        final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
        final ScanSettings settings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setReportDelay(5000)
                .setUseHardwareBatchingIfSupported(false)
                .setUseHardwareFilteringIfSupported(false)
                .build();
        final List<ScanFilter> filters = new ArrayList<>();
        filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(HEART_RATE_SERVICE_UUID)).build());
        scanner.startScan(filters, settings, scanCallback);

        scanning = true;

        handler.removeCallbacks(stopScanRunnable);
        handler.postDelayed(stopScanRunnable, SCAN_DURATION);
    }