Android 4.0 & 4.1 Bluetooth issues. Detect broken comms & dropping pairing
Asked Answered
G

1

11

Hey All,

I understand that Android's bluetooth stack(bluez) was replaced on 4.2. Even though they might have fixed a lot of the previous issues, due to a need to support older versions, i still need to battle with them.

I would appreciate tremendously if someone have dealt with this issues before and could shed some light.

Issue #1 - Unable to detect broken comms (4.0 & 4.1 Android, Bluez bluetooth stack)

The bluetooth app connects to our own custom SPP device ( we use the standard UUID ). It uses a bluetooth service that runs on it's own process. It's required that this app runs for several hours doing bluetooth work.

During power-save / screen lock, the app is kept alive while data is coming in through bluetooth radio, and also i check periodically with a set alarms, where i request CPU time to reconnect & keep doing work (if necessary)

Now; the system is working fine most of the time, but, in some rare situations when the screen is locked and in power-save mode, for reasons i don't understand, upon writing into the output-stream (bluetooth socket) , everything seems to go through without a broken connection being detected. The spp device still states that connection & pairing is valid but receives nothing.

On the Android side, the logs show a native call to BluetoothSocket.cpp::writeNative (assuming it's directly related to the bluez bluetooth stack) that just seems to write the bytes correctly onto the bluetooth radio without reporting any sort of error.

code piece that writes into output stream :

public void write(byte[] bytes) {
            try {
                Log.d(LOGGER.TAG_BLUETOOTH," bluetooth bytes to write : "+bytes);
                mmOutStream.write(bytes);
                mmOutStream.flush();
                Log.d(LOGGER.TAG_BLUETOOTH," bluetooth bytes written : "+bytes);
            } catch (IOException e) { 
                e.printStackTrace();
            }
        }

logcat :

D/com.our.app.bluetooth( 8711): bytes sending : [B@41e0bcf8

D/com.our.app.bluetooth( 8711): bluetooth bytes to write :[B@41e0bcf8

V/BluetoothSocket.cpp( 8711): writeNative

D/com.our.app.bluetooth( 8711): bluetooth bytes written :[B@41e0bcf8

Questions - Is it correct to assume that, apart from application level checking&heartbeats, broken comms should be detected upon socket I/O operations like in this case? Or could the bluetooth radio just go down during power-save ?

Issue #2 - Sudden drop from pairing list.

In Android 4.0 & 4.1, devices in some cases, get unexplainably dropped from the pairing list. Even this is rare and somewhat only in some particular devices... it's a case where prevents the phone to be re-paired and connected easily.

I do notice that the SPP device pairs correctly , but sometimes, the android devices displays the message "Unable to pair to device X, incorrect PIN or Password" .

Note : For android versions < 4.2 we do use insecure comms ( createInsecureRfcommSocket, due to other android connection issues for this versions ).

Questions - How often should this PIN / Password be refreshed during an session?

This could very well be a bug in our SPP device, but on the off chance that is not, any ideas ?

Thanks a million.

Gobang answered 9/10, 2014 at 16:40 Comment(1)
You need to refresh cache look here - https://mcmap.net/q/553761/-bluetooth-not-connecting-on-4-4-2 but I just use insecureSocket on all versionNike
B
1

This is working android 4.4.2 on nexus 7

private boolean refreshDeviceCache(BluetoothGatt gatt){
try {
    BluetoothGatt localBluetoothGatt = gatt;
    Method localMethod = localBluetoothGatt.getClass().getMethod("refresh", new Class[0]);
    if (localMethod != null) {
       boolean bool = ((Boolean) localMethod.invoke(localBluetoothGatt, new Object[0])).booleanValue();
        return bool;
     }
} 
catch (Exception localException) {
    Log.e(TAG, "An exception occured while refreshing device");
}
return false;}


public boolean connect(final String address) {
       if (mBluetoothAdapter == null || address == null) {
        Log.w(TAG,"BluetoothAdapter not initialized or unspecified address.");
            return false;
    }
        // Previously connected device. Try to reconnect.
        if (mBluetoothGatt != null) {
            Log.d(TAG,"Trying to use an existing mBluetoothGatt for connection.");
          if (mBluetoothGatt.connect()) {
                return true;
           } else {
            return false;
           }
    }

    final BluetoothDevice device = mBluetoothAdapter
            .getRemoteDevice(address);
    if (device == null) {
        Log.w(TAG, "Device not found.  Unable to connect.");
        return false;
    }

    // We want to directly connect to the device, so we are setting the
    // autoConnect
    // parameter to false.
    mBluetoothGatt = device.connectGatt(MyApp.getContext(), false, mGattCallback));
    refreshDeviceCache(mBluetoothGatt);
    Log.d(TAG, "Trying to create a new connection.");
    return true;
Balancer answered 15/7, 2015 at 8:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.