polarofficial / polar-ble-sdk

Repository includes SDK and code examples. More info https://polar.com/en/developers
Other
470 stars 152 forks source link

Disconnection after 3 hours of use #224

Open migueBarrera opened 2 years ago

migueBarrera commented 2 years ago

Platform on which you observed the bug:

Device on which you observed the bug:

Describe the bug We use this sdk to connect with the bracelet. we want to record the data overnight. approximately when it takes 3 hours it disconnects.

How to Reproduce connect to the oh1 device with the sdk and spend all night receiving data.

Expected behavior We need to record long sessions.

Questions Are there any limitations? Does Android kill the bluetooh service in any way? What this message means exactly? => "state changed device newState: 0 status: 8" We are thinking on buying a verity sense device. Do you think it may work better?

Screenshots and logs 01-13 02:30:51:071 I/CommunicationService(16568) : BDGattCallback/GATT state changed device newState: 0 status: 8 01-13 02:30:51:074 I/CommunicationService(2) : BDDeviceSessionImpl/disconnected 01-13 02:30:51:087 I/CommunicationService(2) : BleHrClient/Stop observing HR 01-13 02:30:51:090 I/CommunicationService(2) : BleGattBase/Remove notification characteristic for 00002a37-0000-1000-8000-00805f9b34fb 01-13 02:30:51:134 I/Reporter(2) : trail step: Error on CommunicationService, message = null 01-13 02:30:51:169 W/Reporter(2) : Error on CommunicationService, message = null com.polar.sdk.api.errors.PolarDeviceDisconnected at com.polar.sdk.impl.BDBleApiImpl.handleError(BDBleApiImpl.java:1092) at com.polar.sdk.impl.BDBleApiImpl.lambda$startStreaming$29$com-polar-sdk-impl-BDBleApiImpl(BDBleApiImpl.java:697) at com.polar.sdk.impl.BDBleApiImpl$$ExternalSyntheticLambda26.apply(Unknown Source:4) at io.reactivex.rxjava3.internal.operators.flowable.FlowableOnErrorNext$OnErrorNextSubscriber.onError(FlowableOnErrorNext.java:94) at io.reactivex.rxjava3.internal.subscribers.BasicFuseableSubscriber.onError(BasicFuseableSubscriber.java:101) at io.reactivex.rxjava3.subscribers.SerializedSubscriber.onError(SerializedSubscriber.java:144) at io.reactivex.rxjava3.internal.operators.flowable.FlowableDoFinally$DoFinallySubscriber.onError(FlowableDoFinally.java:89) at io.reactivex.rxjava3.internal.operators.flowable.FlowableCreate$BaseEmitter.errorDownstream(FlowableCreate.java:299) at io.reactivex.rxjava3.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:539) at io.reactivex.rxjava3.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.signalError(FlowableCreate.java:489) at io.reactivex.rxjava3.internal.operators.flowable.FlowableCreate$BaseEmitter.tryOnError(FlowableCreate.java:287) at com.polar.androidcommunications.common.ble.RxUtils.postError(RxUtils.java:45) at com.polar.androidcommunications.common.ble.RxUtils.postExceptionAndClearList(RxUtils.java:29) at com.polar.androidcommunications.api.ble.model.gatt.client.pmd.BlePMDClient.clearStreamObservers(BlePMDClient.kt:462) at com.polar.androidcommunications.api.ble.model.gatt.client.pmd.BlePMDClient.reset(BlePMDClient.kt:88) at com.polar.androidcommunications.enpoints.ble.bluedroid.host.BDDeviceSessionImpl.handleDisconnection(BDDeviceSessionImpl.java:312) at com.polar.androidcommunications.enpoints.ble.bluedroid.host.BDDeviceListenerImpl$4.deviceDisconnected(BDDeviceListenerImpl.java:371) at com.polar.androidcommunications.enpoints.ble.bluedroid.host.connection.ConnectionHandler.deviceDisconnected(ConnectionHandler.java:87) at com.polar.androidcommunications.enpoints.ble.bluedroid.host.BDGattCallback.lambda$onConnectionStateChange$6$com-polar-androidcommunications-enpoints-ble-bluedroid-host-BDGattCallback(BDGattCallback.java:72) at com.polar.androidcommunications.enpoints.ble.bluedroid.host.BDGattCallback$$ExternalSyntheticLambda2.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:914) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:225) at android.app.ActivityThread.main(ActivityThread.java:7563) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:994)

JOikarinen commented 2 years ago

Hi @migueBarrera

quick first thoughts.

The problem, that OH1 disconnects, may happen because of battery getting low in OH1. I will investigate can there be other logic build into the OH1 which could cause the sudden disconnection. For now I can't remember such logic, but I will double check.

On the other hand, disconnect may happen by the Android OS too. From the logs, I assume, that BLE connection is kept up by service called CommunicationService in your app. Is that a foreground service?

What this message means exactly? => "state changed device newState: 0 status: 8"

newState: 0 is STATE_DISCONNECTED status: 8 is connection timeout. What could indicate the OH1 has been outside of BLE range and thus the disconnection. Could that explain the disconnection?

lmiceli commented 2 years ago

Hi @JOikarinen thanks for the reply. I am @migueBarrera's coworker. Yes you are correct that Service is set as foreground. Sadly this issue appears after some time which is never short (hard to debug) and we make sure never to be more than 1 meter away from phone. We have 3 oh1 with latest firmware and tried on different phones. We use latest version of polar api. Any insights will be greatly appreciated Cheers!

JOikarinen commented 2 years ago

Hi @lmiceli,

I did little bit more investigations on what is the status parameter on different BLE disconnection scenarios, i.e. what is thestatus parameter given by onConnectionStateChange callback. This is a bit hard because Android documentation is listing only few of them. To understand them all needs deep dive into AndroidOS open source repositories, I didn't go that deep yet. 🙂

However, this is what I learned for now:

@lmiceli even though the scenario is hard to debug (as it takes long to reproduce), do you still always face the problem in your environment or does it happen every now and then?

JOikarinen commented 2 years ago

I investigated this issue a small step further.

If the OH1 runs low of battery, around 6% battery left, it closes the BLE connection: GATT state changed device newState: 0 status: 19

status is 19, as expected, because the connection is disabled by the OH1. To run the battery down took me around 6hours and the BLE connection was staying up for that time.

One important question is that which data stream(s) you have requested when the problem happens?

lmiceli commented 2 years ago

hi @JOikarinen many thanks for the continued research.

the error that we are facing happens almost every night, always with the status 8. With our app it seems the battery is not being drained, even when the session gets longer than 6/7 hours (the few times it worked)

we were hoping the issue could be some battery saving on the side of oh1 but your research and comments suggest we need to keep looking at android and our code.

        polarApi = PolarBleApiDefaultImpl.defaultImplementation(this, PolarBleApi.ALL_FEATURES)
        polarApi?.setPolarFilter(true)
        polarApi?.setAutomaticReconnection(true)

Adding the api config lines in case it helps. Thanks again and have a great weekend