BLE scanning stops device discovery when the screen is locked for Samsung S6 - bluetooth-lowenergy

I am developing an app to scan for the peripheral devices using the Android phone.
When the Application tested using Samsung S6 device (Model used are Indian, EU and US version), I have seen that the device stopped discovering the BLE devices during scanning as soon as the phone screen is locked.
It almost took 4-5 hours to resume the discovery when the phone kept in same locked state.
Configuration Details:
Lollypop Scanner with scan filter UUID's using Low Power Mode.
ignore Battery Optimization was set to True.
Phone screen locked after some time when the scanning was started.
Samsung Models used: SM-G920F, SM-G920A
Test results :
The app was able to see the discovery when it was in the foreground and device discovery stopped immediately when the phone screen was locked.
Important Note : The same application is working fine on Samsung S7,S8,S9 and pixel

Related

BLE connection fails on Android - Invalid pin or passkey

I am working on a mobile app that connects to accessories over BLE. The app runs on Android as well as iOS.
I have a Raspberry Pi that is running a BLE server app.
When my Android app tries to connect to Pi over BLE, the connectivity just fails. I see a system notification popping up that Bluetooth connection failed because of an invalid pin or passkey.
However, my iOS app seems to connect just fine. There is no PIN or passkey requested.
I have tried Android testing with Pixel 2 as well as Pixel 3. The OS version is 10.
My Android app used to work fine until a few months ago. I feel it must be a recent change in Android OS.
I am wondering if anyone else has seen such a problem. Thanks.

How to build an android app that acts as a peripheral bluetooth, so I can discover it from iOS application?

I have built an iOS app that uses corebluetooth, and an android app that starts avertisement via GATT server.
So Android devices only discover other androids and iOS devices.
And iOS devices discovers other iOS' only.
The question is how to advertise data from android so iOS devices can discover it, or is there any way for iOS device to scan regular bluetooth devices except for MFi program?
if you had any experience with connecting these two OS via bluetooth, please let me know the ways on how to do it.

BLE: Reconnect Android central to iOS peripheral

After days of research and trial and error my colleagues and I have to hope that the StackOverflow community has a working solution.
We got an Android Smartwatch. We developed an app which acts as the BLE central. The App shows a QR-Code encoding an UUID which is unique for every Smartwatch. While showing that QR code it's actively scanning for a device advertising a service with that UUID.
We also developed an iOS app which can scan that QR code and start advertising with the service UUID it received. The Android Smartwatch then connects very quickly to the iOS device.
One purpose of the Smartwatch is to show push notifications from the iOS device. So when the connection is successfully established, the Smartwatch-App subscribes to the ANCS Data Source and Notification Source characteristics. This initiates "Just Works" pairing, so you just have to click on "Pair" on the iOS device. Afterwards you have to allow that iOS notifications are shared to the Smartwatch and then the Smartwatch successfully receives notifications.
ANCS is also the reason why the iOS device MUST BE in the peripheral role.
Until here everything works fine.
When the user leaves the bluetooth range or dis- and enables bluetooth on the iOS device, an automatic reconnect should be triggered. It DOES reconnect when the iOS app is in foreground. Unfortunately it DOES NOT work when the iOS-App is in background. This is probably related to the fact, that the iOS device is not advertising with the required UUID when the app is in background as described in the CoreBluetooth documentation:
All service UUIDs contained in the value of the CBAdvertisementDataServiceUUIDsKey advertisement key are placed in a special “overflow” area; they can be discovered only by an iOS device that is explicitly scanning for them.
We tried many different ways to reconnect from the Android Smartwatch to iOS. From my understanding it should be working when making the first connectGatt with autoConnect=false and when the connection is lost, calling connectGatt on the lost device with autoConnect=true, but it never reconnects. At least not within 15 minutes. Scanning again also wouldn't work, as the UUID is not advertised in background anymore.
We also tried to additionally let the Android device act as peripheral, so the iOS can connect to it. After connecting we wrote data to an "INITIATE_ANCS"-characteristic and let the Android device call connectGatt on the device which was passed to onCharacteristicWrite. This led to interesting behavior:
- The connection was working, we could read a Smartwatch-Characteristic from iOS.
- When subscribing to the ANCS characteristics, it initiated pairing. But instead of "Just Works" pairing it showed a 6-digit code on the iOS device which we had to type onto the Smartwatch.
- The pairing was inititated on every new connect and it always created a new device in the systems device managers on both Android and iOS.
- The pairing WAS NOT inititated when the iOS app was in background.
We really did a thorough research and couldn't find a solution. Did we understand something wrong on how BLE for iOS and Android works? We really hope to find an expert here that has the knowledge what has to be done to make the reconnect work.
Edit:
The Android device is running on Android 5.1.1 and currently it's no option to update.
The iOS testing device is running iOS 13.3 and it should be compatible with iOS 13+

Is there any standard way to make our own BLE accessory device auto re-connectable in iOS /Android?

I'm wondering whether or not we can make a specific BLE peripheral device with having this ability to be supported by iOS/Android for automatic scanning for automatic reconnecting, i.e without using any extra app.
I think some standard BLE accessory devices (like Heart sensor) are already known by smartphones, so after first-time pairing, the smartphone's OS itself will scan for finding them again automatically for re-connecting each time when the connection gets lost.
Yes. If the device is a HID device then the system will auto connect to the device until you disable it in Android and unpair it in iOS.
But what's the purpose if you don't have an app?

What is the max concurrent Ble connections android M+ can have

My app required to connect 9 Ble devices concurrently.
In this article and any other resource it write that android 4.4+ can connect only to 7 devices.
Is there anything new in M or N versions?
Thanks.
The number of connections is limited by the constants MAX_L2CAP_LINKS and GATT_MAX_PHY_CHANNEL which is currently (still) set to 7.
If you try to connect the 8th device with autoConnect = true, the stack will hang and fail to connect again until you restart Bluetooth due to a bug introduced in Android M. If you use autoConnect = false to connect an 8th device you will immediately get an onConnectionStateChange callback with newState = disconnected and no attempt to connect will be made.
I don't know why these constants are so low. Often the hardware itself can do more than 7. For example, Nexus 6P can do 15 if you compile AOSP yourself and change the constants.
Samsung seems to have noticed the issue and increased the constants on some of their devices. For example, Samsung Galaxy Tab A 10.1 can handle 15 BLE connections without modifications.
It seems that those constants are global limits, and not per app. I am linking to the source of the BT stack in Android. I wonder why those constants are as they are... seem random.
#define GATT_MAX_PHY_CHANNEL 7
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/include/bt_target.h#1428
#define BTA_GATTC_CONN_MAX GATT_MAX_PHY_CHANNEL
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/bta/gatt/bta_gattc_int.h#89
tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX];
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/bta/gatt/bta_gattc_int.h#424
NOTE
This is the official Android code. Up until Android 7.2 the vendors used to change that implementation a lot. The theory in Android 8 and above is that vendors should not modify it (not enough Android 8 devices on the field to see how this works in practice... at least at time of writing this reply).

Resources