Android Question Checking if Bluetooth is Disconnected Issue

Taylor Chapman

Member
Licensed User
Longtime User
Hi there,

I'll briefly explain the problem and then add related coding. I start by auto-connecting to bluetooth in activity MAIN and once connected, I start activity CENTRAL. My goal is to monitor the bluetooth connection and if it breaks, send the program back to the beginning of MAIN. Initially I declare BT As BluetoothAdmin and I am currently using that to return the status.

B4X:
Sub Activity_Create(FirstTime As Boolean)
   
    'StartActivity(Central) '*** TO ACCESS CENTRAL
   
   
    Activity.LoadLayout("setup")
   
End Sub 'Loads Layout 1 and initializes serial and BT COM

Sub Activity_Resume
       
    'MyDeviceName = "Put the name of your coupled device here!"
    MyDeviceName = "HC-06"
    ToastMessageShow("Connecting to  " & MyDeviceName, True)
    timBT.Initialize("timBT",5000)
    timBT.Enabled = False
   
    Try
        BT.Initialize("BT")
        Serial1.Initialize("Serial1")
    Catch
        ToastMessageShow("No BlueTooth Device visible...", True)
    End Try
   
       
       
        'Start Bluetooth
        Try
            If BT.IsEnabled = False Then
                lblBT.Color = Colors.Black
                BT.Enable
            Else
                'connect to SK
                BTConnectToDevice
            End If
        Catch
        End Try

End Sub ' Calls "BTConnectToDevice

Sub BTConnectToDevice
    Dim PairedDevices As Map
   
    PairedDevices = Serial1.GetPairedDevices
    Try
        Serial1.Connect(PairedDevices.Get(MyDeviceName))
    Catch
        ToastMessageShow("Device not available",True)
    End Try
End Sub ' Pairs with HC-06

Sub BT_StateChanged(NewState As Int,OldState As Int)
    If NewState = BT.STATE_ON Then
        BTConnectToDevice
        Log("BT Connect")
    Else
        Serial1.Disconnect
        timBT.Enabled = False
        Log("BT Disconnect")
    End If
End Sub ' Originally found IN MAIN.

Sub Serial1_Connected (Success As Boolean)
   
    If Success = True Then
        ToastMessageShow("Bluetooth connected to " & Serial1.Address, False)
        timBT.Enabled = True
    Else    'disconnected
        ToastMessageShow("Connection to " & Serial1.Address & _
                        " broken!", True)
        timBT.Enabled = False
        errorSelection
    End If
End Sub ' Once connected to HC-06 will enable timBT timer.

Now the above bluetooth connects fine and runs fine; once connected, I direct the program to a different activity (Central). In central I have the following code...

B4X:
Dim BtCheck As Timer

B4X:
    BtCheck.Initialize("BtCheck", 1000)
    BtCheck.Enabled = True

B4X:
Sub BtCheck_tick

    If Main.BT.IsEnabled == False Then
        StartActivity(Main)
    End If

End Sub ' Will check if BT active

Now if I alter the if statement to only implement when ( BT.IsEnabled == true ) it directs back to main as it should - so the timer seems to be functioning correctly.

However when I do disconnect the bluetooth device it seems that Main.Bt.IsEnabled remains True. I'm not sure why this would be; if the connection is broken, will it not change the status automatically?


Any help would be very appreciated!
Thanks
Taylor
 

Taylor Chapman

Member
Licensed User
Longtime User
Erel,

Thanks for your reply - I've moved the bluetooth setup into a service and it works well.

I'm still unable to detect a bluetooth disconnect; I'm using the AsyncStreams_Terminate event as you suggested, but it doesn't seem to trigger when I unplug the bluetooth device.

B4X:
Sub AsyncStreams_Terminated
   
    Serial1.Disconnect
    ToastMessageShow("Bluetooth Connection Error!", True)
    StartActivity(Main)

End Sub

The above code is running in the service, but it is not called even after unplugging the bluetooth. Any thoughts?

Thanks!
Taylor
 
Upvote 0

Taylor Chapman

Member
Licensed User
Longtime User
AsyncStreams_Terminated seems closer to what I'm looking for (if the connection is unexpectedly terminated) - I've tried the error version though and the sub still isn't called. Maybe I am misunderstanding the way they are called? Is it necessary to use both terminated and error subs for some reason?

Alternatively, I could just keep a timer ticking to check the bluetooth connection - is there any way of returning the status of the connection within a sub?

Thanks!
Taylor
 
Upvote 0

Taylor Chapman

Member
Licensed User
Longtime User
Is it possible to explain exactly why/when the error and terminated events are raised? I cannot seem find anything beyond a couple sentences regarding them.

Also, by "heartbeat" solution, I'm assuming you mean have a check running maybe every 100ms or so (correct me if I'm wrong). For that to work I need a Property that will return the actual connection status of the bluetooth; do you know of any?

Edit: I should point out that I am not working in prefix mode if that makes any difference.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
AsyncStreams tries to read from the stream with a background thread. There are three possible outcomes:
- The thread waits until one or more bytes are available and then the NewData event is raised.
- An error happens and the error event is raised.
- The native API returns -1 which means that the connection is closed. The Terminated event is raised.

This is a bit simplified. The actual implementation is more complicated.
 
Upvote 0

Taylor Chapman

Member
Licensed User
Longtime User
Erel, thanks for all your help so far! I have it working now and would just like to clarify a couple more things.

Firstly, I'd like to confirm that it is only necessary to close the serial connection and AsyncStreams if the error event is raised and not if the terminate event is raised.

Now secondly, the error event is indeed raised whenever I attempt to make connection with the BT; that is, when the user changes the tablet interface. Unfortunately though, there seems to be a period of three or four seconds after the user changes the tablet before the error event is raised - why is this not practically instantaneous?

EDIT: Actually, the error seems to occur a few seconds after disconnection regardless of whether or not data is sent. That's good, but I'm still looking to see how to minimize that time.

Thanks!
Taylor
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
why is this not practically instantaneous?
The error is raised immediately when the underlying native API reports about it.

that is, when the user changes the tablet interface.
You should use a service to manage the connection. The connection should not be affected from the activity life cycle.
 
Upvote 0
Top