Reedyuk / blue-falcon

A Bluetooth kotlin multiplatform "Cross-Platform" library for iOS and Android
https://bluefalcon.dev
Apache License 2.0
321 stars 43 forks source link

Bluetooth not work on Android 11 API 30 #120

Closed youvita closed 2 weeks ago

youvita commented 4 months ago

Any help, when I clicked scan is started status. However don't display any bluetooth found. Noted: Bluetooth and permission is turn on status

Screenshot 2024-04-30 at 3 14 48 PM Screenshot 2024-04-30 at 2 43 36 PM
Reedyuk commented 4 months ago

It would appear that bluetoothadapter.java is throwing an exception. If you click into it you will see the code and find why this is the case. Usually the stacktrace is bigger and you will find the original cause lower down(its cut off on your screenshot). Chances are, this is an issue with android.bluetooth.BluetoothAdapter(standard android) and not an issue with the blue falcon library. It could be a permissions issue, seems like there is a fetching of systemService from a context wrapper. - Permission with xml manifest?

youvita commented 4 months ago

Yes, I also added the permission in manifest. However I tried with other device android version 14 API 34 it's working. That's why I think the issue come from version android device.

Reedyuk commented 4 months ago

So it works on version 14 API 34 of android. Which version of android does it not work? What is the full stack trace? you will probably find a hint of the error there

youvita commented 3 months ago

The currently android version 11 API 30 not work. The actually I try run the same source code but the version 11 of android not list bluetooth found. however it's work on version 14 API 34 Noted: both device also turn on bluetooth and clicked scan button.

Device not work 2024-05-02 09 27 51

Device work 2024-05-02 09 26 43

Reedyuk commented 3 months ago

Do you have the full stacktrace? could you post it in here?

youvita commented 3 months ago

I'm not sure what is the full stack trace. However I have to explore logs file, may it's can help.

OnePlus-ONEPLUS-A6000-Android-11_2024-05-02_152223.logcat.zip

Reedyuk commented 3 months ago

Having a look now for you

Reedyuk commented 3 months ago

Are you sure you have the correct permissions:


    /**
     * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
     * by BLE Always on enabled application to know the ACL_CONNECTED event
     * when Bluetooth state in STATE_BLE_ON. This denotes GATT connection
     * as Bluetooth LE is the only feature available in STATE_BLE_ON
     *
     * This is counterpart of {@link BluetoothDevice#ACTION_ACL_CONNECTED} which
     * works in Bluetooth state STATE_ON
     *
     * @hide
     */
    @RequiresBluetoothConnectPermission
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_BLE_ACL_CONNECTED =
            "android.bluetooth.adapter.action.BLE_ACL_CONNECTED";

My guess is that you dont have the bluetooth_connect permission.

public static final String BLUETOOTH_CONNECT = "android.permission.BLUETOOTH_CONNECT";

youvita commented 3 months ago

Yes, I'm sure. Because I'm just from from your source code.

Screenshot 2024-05-02 at 3 42 16 PM
Reedyuk commented 3 months ago

i would need to spend time looking into this properly, will have to try later when i have a moment. My guess is its something around contexts and permissions used in an older api of android. Not the best solution but i would propose you don't support the older api bump the minimum up.

youvita commented 3 months ago

Thanks for your help

Reedyuk commented 3 months ago

@youvita - i have tried to recreate the issue but because i dont have a physical android device on android 11, i cannot reproduce. The emulator doesnt crash but obviously it doesnt engage with bluetooth. As a suggestion i could bump the min api level so that android 11 cannot be supported but that wont fix your problem of supporting those devices.

youvita commented 3 months ago

@Reedyuk, I have question, it's possible to display bluetooth name instead bluetooth address? Example: 77:D9:EE:E6:E2:52 -> U6-LR

Reedyuk commented 3 months ago

Ble devices expose a characteristic called name, you must call this and then in your app, display the value of this characteristic.

youvita commented 3 months ago

@Reedyuk, Could you update this name bluetooth address instead characteristic as you mention above? It's better know the name of Bluetooth device. Thank you for feedback.

327294141-e9f7a13a-dbd0-44ef-ba85-cf8fec50f96b

Reedyuk commented 3 months ago

No, as this is only an android thing and also this could have an impact on other users of the library. It is up to you, the consumer of the library to do this your side.

youvita commented 3 months ago

It's possible, you can mention the example code here. Thanks for support.

Reedyuk commented 3 months ago

Sorry, you will have to do that yourself.

The sudo is rather simple: Detect device, request characteristic of 'name', when you get the value then display.

You could even extend the BluetoothPeripherial, to have a suspend func to get the Mac address.

Then in your client code, you could have a flow of devices mapped to by key to device e.g.

val deviceMap: MutableStateFlow<Map<String, BluetoothPeripherial>> = blueFalconClient.peripherals.map {
it.macAddress() to it
}
Reedyuk commented 2 weeks ago

Hi, @youvita - i have managed to get my hands on an old android device. I found that older versions of android require ACCESS_FINE_LOCATION permission in addition to the others.

if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.R){
            requestPermissions(
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                0
            )
        }

A simple request of the above in your activity will resolve the issue. I have updated the kotlinMP-example to reflect this. IMG_0963