Android app which interacts with BLE devices not working on Chromebook - android

I have an Android app which interacts with custom BLE devices. This app works as expected on devices which have android version 4.4 to 6.0. Now I want to make this available on Chromebooks through the Google Playstore on Chromebooks(App Runtime for Chrome).
I installed this app on my Google Asus Flip Chromebook(Chrome OS version 55, ARC version 3617689) by sideloading the APK onto it. But it is not working as expected.
These are the steps I took:
Call a startLeScan() which gives the BluetoothDevice as a scanResult.
Call the connectGatt() method, and the device is connected and in the onConnectionStateChange() callback, get a handle to the BluetoothGatt.
Call the discoverServices.
After that, the onServicesDiscovered() callback is hit as expected with status = GATT_SUCCESS.
However gatt.getServices returns an empty list when running on Chromebook. When running on Android device (API 19 to API23) I get BluetoothGattService handles to all the services supported by my BLE device.
Which leads me to suspect the BLE implementation on ARC on Chromebook.
Has anybody else faced this issue? Is anyone using Android BLE APIs on Chrome OS?

I've having the same trouble, and it appears to be a deficiency with the BLE implementation on Chromebooks. Although there isn't a fix or workaround, the issue is being tracked at https://bugs.chromium.org/p/chromium/issues/detail?id=722987

Related

BLE device not showing up in Android Chrome

I have a Bluetooth Low Energy (BLE) device and want to access it from a web page using the Web Bluetooth API.
This works perfectly fine in Chrome on Windows (at least with current versions of Chrome and Windows) and even with the WebBLE App on iPadOS (since Safari won't support WebBluetooth).
But I have multiple Android devices running the current versions of Android (12) and Chrome (97), where in the browser device chooser, the device won't show up. Some other unknown devices show up, but my device does not.
What could be the reason just this one device does not show up and how could I gather more information about this situation?
It happens in the native browser dialog so my usual debugging steps don't work.
Update:
I have already checked with chrome://bluetooth-internals, and the result is the same. The device shows up on Chrome/Windows but not on Chrome/Android.
Now I also used chrome://device-log which on both Windows and Android shows only
Bluetooth Internals Page initiating Bluetooth discovery session
nRF Connect for Mobile shows the device instantly, and it also shows up in the Android Bluetooth settings. Only Chrome Web Bluetooth doesn't show it.
Update2:
The adb logcat reveals the following line during Chrome Bluetooth discovery:
V/BtGatt.GattService(19403): Skipping data matching denylist
What's that? Has Chrome its own denylist for bluetooth devices?
Update3:
Android has a denylist for BLE devices, which should not be applied if the App (Chrome) has ACCESS_FINE_LOCATION permissions. But Samsung seems to apply the denylist nonetheless, even if Chrome has all necessary permissions.
https://www.chromium.org/developers/how-tos/file-web-bluetooth-bugs/ lists tools and log viewing approaches thay may help, including:
chrome://bluetooth-internals
nRF Connect for Android
chrome://device-log
Try requestDevice with "acceptAllDevices":true as well if you haven't yet.
It is unfortunate that this device is getting filtered out even though it isn't a location beacon (iBeacon, eddyStone) but this behavior is currently working as intended according to https://bugs.chromium.org/p/chromium/issues/detail?id=1296054.
The reason the device is not showing up is that Android has a denylist which matches Eddystone and iBeacon payloads using the advertising data.
My device seems to have something in its advertising data which matches Eddystone or iBeacon and thus is ignored, even though it is a digital tape measure.
Sources:
https://android.googlesource.com/platform/packages/apps/Bluetooth/+/master/src/com/android/bluetooth/gatt/GattService.java#255
https://android.googlesource.com/platform/packages/apps/Bluetooth/+/master/src/com/android/bluetooth/btservice/AdapterService.java#3939

Disconnection events from android bluetooth le peripheral are not sent

Currently testing the latest Android 7.1.1 developer preview (NPF26F) and running into this weird behavior with Bluetooth LE:
Open GattServer from device A
Establish Gatt connection from device B to device A (Connection is successfully established)
Force Stop app in device A (GattServer)
At this point, the expected behavior would be that The GattServer in device A would be closed and all connections to it would also be closed, however this doesn't seem to be happening as no disconnection event is thrown to the BluetoothGattCallback in device B.
It seems that the only way to cut the connections and stop the GattServer is to turn off the Bluetooth antenna.
I've already reported this issue here: https://code.google.com/p/android/issues/detail?id=228432 but only got a confusing reply on how to work aroud it (which by the way, doesn't work)
Is this working as intended? Or is there something i can do to properly report disconnection events?
Edit: It seems that this only happens with the Nexus 5x and Nexus 6p with the latest developer preview NPF26F. I've also tested with other devices with API 23 and they seem to be working correctly.

Android Bluetooth device scanned only one time

I'm working on an Android app that needs to connect to a Bluetooth Low Energy device.
The app is working correctly on most devices but i had troubles with some devices (One plus One with Cyanogene Android 4.4.4 and Sony C5303 with Android 4.3) using BluetoothAdapter.startLeScan().
With the One plus, the problem seems to be the same as related in this post: Android 4.3: BLE: Filtering behaviour of startLeScan() the Bluetooth device is only scanned once. If I connect then disconnect from the device, it is not scan it again.
After some test I tried using: BluetoothAdapter.startDiscovery() in addition to BluetoothAdapter.startLeScan().
It appears that my device is now correctly scanned multiple times and my LeScanCallback is correctly called. I can then connect/disconnect from my BLE device.
Question is:
How BluetoothAdapter.startDiscovery() can interact with BluetoothAdapter.startLeScan() to allow my device being detected multiple times ?
Thanks for you help !
You should calling 'stopLeScan()' correctly. After adding stopLeScan your device should be detected correctly.

How to connect Android device to an iOS device over BLE (Bluetooth Low Energy)

I'm trying to make an application which uses the new Bluetooth Low Energy API of Android. For this, I started with the BLE sample coming with API level 18.
As I read that Android can not act as a Peripheral, I put the Android phone in central mode, scanning for BLE devices around it. For this purpose, I made some testing with a Nordic Platform simulating a Heart Sensor. Everything works in a perfect way!
After this, I try to pick an iPhone (iOS 7 beta 4) and put it in a Peripheral way and simulating a Heart Rate sensor as the previous testing. The Android app is able to see the device and connect to it. But after the connection is active, the 2 devices disconnect from each other in 3-4 seconds. In addition to that, when I call discoverServices() on Android side, no callback is triggered! In some cases the Android device receives the "Connected" event even if iOS Bluetooth chip is Off. This is very strange. To prove that, I put the Nordic Board in Central mode and I was correctly able to connect to the iOS device with no problems.
What could it be? There are some limitations on Android or iOS that don't permit to connect from an Android to an iOS or viceversa?
Thanks.
EDIT: After some hard testing, I raised an issue on the AOSP page. It can be checked here
Adding a summary for reference:
What could it be? There are some limitations on Android or iOS that don't permit to connect from an Android to an iOS or viceversa?
When connecting to a GATT server that is advertised as dualmode (BLE and BR/EDR) device by calling connectGatt(...), the TRANSPORT_AUTO flag that is internally added makes Android to default to the BR/EDR mode (link).
Following workarounds are possible:
Peripheral side: Stop advertising BR/EDR capabilities by adjusting
the appropriate flags (link)
Central side: Set the transport parameter explicitely to
TRANSPORT_LE by calling the hidden version of connectGatt() using
reflection
Example:
public void connectToGatt(BluetoothDevice device) {
...
Method m = device.getClass().getDeclaredMethod("connectGatt", Context.class, boolean.class, BluetoothGattCallback.class, int.class);
int transport = device.getClass().getDeclaredField("TRANSPORT_LE").getInt(null); // LE = 2, BREDR = 1, AUTO = 0
BluetoothGatt mGatt = (BluetoothGatt) m.invoke(device, this, false, gattCallback, transport);
...
}
Edit 4/2016
As Arbel Israeli pointed out in the comment, Google introduced an overloaded version of connectGatt(...) which allows to specify the transport in Android M.
I've written a simple working example, well relatively simple, and included it open-source on Github: https://github.com/GitGarage. So far it has only been tested with an Android Nexus 9 and an iPhone 5s, but I presume it would also work with a Nexus 6 and various iPhone types. So far it is set up explicitly to communicate between one Android and one iPhone, but I presume it is tweakable to do much more.
Maybe a bit delayed, but perhaps your pain can be relieved slightly ;)
We have been experimenting a lot with cross platform BLE connections (iOS<-> Android) and learned that there are still many incompatibilities and connection issues. Aside to the instability of Android you should also consider that still, as of today, not that many Android devices actually support the BLE Peripheral mode.
Therefore, if your use case is feature driven and you only need basic data exchange I would suggest to look at Frameworks and Libraries that can achieve cross platform communication for you, without you needing to build it up from scratch.
For example: http://p2pkit.io or google nearby
Disclaimer: I work for Uepaa, developing p2pkit.io for Android and iOS.
You can now pass in TRANSPORT_LE via BluetoothDevice.connectGatt as of API 23.
Please see Android Documentation references below:
TRANSPORT_LE
Bluetooth.connectGatt
iOS Devices always be a peripheral or central but Android devices cant be rarely.In this case your iOS device must be a peripheral and android must be a central.We can think peripheral is a server and central is a client.This is simple.

Android Bluetooth 4.0 automatically shut down without exception.

Well, recently Google release the Android 4.3, and it support Bluetooth 4.0 device connection. Unlucy, I have a bluetooth 4.0 project before this appear. My testing phone is Samsung S4, so I can only use SamsungBLEConnect to implement the first version of my apps. And I meet a unexpected situation.
The bluetooth connector(hardware) and Wifi will automatically shut down by itself without any exception.
After this happen, we need to reactivate the bluetooth and wifi by using system setting. This is surely unacceptable for any client. And I don't believe we can program the apps to activate the bluetooth and wifi, as we surely cannot disable the client's bluetooth and wifi by any exception or logical error.
So, the situation is very weired, and the reason of this accident is unknown.
Restart your mobile first and then check it out

Categories

Resources