1

I am working on implementing an Android app that connects to BLE devices but the lack of proper documentation is killing me. Nothing seems to be working the same way twice if I run the app once it might work but the next time stops somewhere(no idea where) but I kinda came to a conclusion that I might have not been using disconnect() and close() in the right order.

After let's say an error I call disconnect() first:

 public void disconnect() {
    mScanning = true;
    mConnected = false;
    startedConnect = false;
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        scanLeDevice(true);
        return;
    }
    mBluetoothGatt.disconnect();
    scanLeDevice(true);
}

then I call close():

public void close() {
    if (mBluetoothGatt == null) {
        return;
    }
    mBluetoothGatt.close();
    mBluetoothGatt = null;
}

Is this the correct way of doing it or wrong? Please be aware that I am calling scanLeDevice(true); right after disconnecting but then close() is called which I think is just "finishing" everything and stops the scanning right?

  • 1
    Did you try finding examples on google? I used the search terms "java android bluetooth" and found many. – NomadMaker Mar 30 '20 at 02:13
  • @NomadMaker I did but nothing that really works, either too old, lack of explanation moreover that my app is a bit different from what i found. –  Mar 30 '20 at 02:27
  • Did you add lowenergy to the list of terms? – NomadMaker Mar 30 '20 at 02:30
  • @NomadMaker yes of course. I have been researching for weeks about this but maybe because I am new to android. Do you have an answer to my question? –  Mar 30 '20 at 02:37
  • No. I was giving what I found. Those links contained the docs and examples. – NomadMaker Mar 30 '20 at 02:40
  • @NomadMaker one thing, would it make better sense if I call `scanLeDevice(true)` inside `close()` ? –  Mar 30 '20 at 02:45

1 Answers1

2

When you create a BluetoothGatt object by calling connectGatt on a BluetoothDevice, you claim one of the 32 (in current Android version) available slots in the Bluetooth stack.

On this object you can now call connect and disconnect to change the state of the "goal" if Android should try to keep a connection to the device or not. Until you call disconnect, Android will (forever) try to connect to the device and automatically reconnect to the device if the connection drops for any reason. Calling connect again after disconnect will make it try to connect again.

Note: setting autoConnect to false in the initial connectGatt call will set an initial timeout for the first implicit connect attempt (usually 30 seconds), and if the device connects and the connection later drops, it won't automatically try to reconnect.

So the BluetoothGatt object can be in the "disconnected" state but still take up one of the 32 slots in the Bluetooth Stack. When you call close, you release all the resources for the BluetoothGatt object and return the slot to the Bluetooth stack. A close therefore implicitly also means disconnect. To potentially workaround some buggy Android devices, you could call disconnect on the BluetoothGatt object before close. Note that once you have called close, you can't call any other methods on that BluetoothGatt object.

Note: turning off Bluetooth means destroying all BluetoothGatt objects automatically.

Back to your question, I don't really understand what your BLE scanning has to do with connect/disconnect/close. Scanning is totally separate from connections and BluetoothGatt objects and there are no issues with being connected and performing a scan at the same time. To stop the scan, call stopScan on the BluetoothLeScanner.

Emil
  • 16,784
  • 2
  • 41
  • 52
  • thanks for your reply. I have read different things about BLE operations in different forums. Many are saying that I must stop scan before connecting because the scanning interferes with connection but you are saying it doesnt?! –  Mar 30 '20 at 17:08
  • I dont understand another thing you are saying _"Note that once you have called close, you can't call any other methods on that BluetoothGatt object"_ but how can I re-call scan()? Please check my code and give me an answer if I am doing it correctly there and if not please do an Edit of your answer using my code so that I have it clearer because I am kinda confused. –  Mar 30 '20 at 17:11
  • 1
    No, scan does not interfere with connections. Maybe six years ago or so a few budget phones had some bugs regarding this, but that should be solved a long time ago. What's your issues regarding "how can I re-call scan"? Please show your full code because now you don't show your scan code. Please also show what you have tried. The documentation for BLE scanning can be found at https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner. – Emil Mar 30 '20 at 22:05
  • I just wanna know if doing this whenever I want to disconnect and restart scanning is the right approach: disconnect(), close() then StartScan(). –  Mar 30 '20 at 23:39
  • 1
    Calling `disconnect` followed by `close` on a `BluetoothGatt` object, followed by starting a BLE scan is perfectly fine. In your own `disconnect` method, I don't understand why you start the scan there however. To me it makes more sense to start a scan after `close` (even if there's no restrictions when you start the scan). – Emil Mar 30 '20 at 23:50
  • yea you are right and sorry I did not change the code in the question but I am actually doing it like that. I removed the startScan from the disconnect() and placed it in another method where I set some flags as well. –  Mar 30 '20 at 23:53