Android Question BT Confusion

Terradrones

Active Member
Hi All

I think my Brain cells are decreasing with old age and I need help as usual please.

Using the BT Library, I can see other BT devices around me. When I want to connect, it gives me an error message all the time and I cannot connect.

I have had a look at Erel's Bluetooth Chat example and I come to the conclusion that the only way that this will work is if both devices run the same program.

How do I go about connecting to an external GPS or Total Station (an instrument that measures angles and distances) using BT?
 

Terradrones

Active Member
Does this mean that your program displayed and allowed you to select the instrument? Did Connect return True. If so then I suspect you haven't set up the input and output streams. Look carefully at the EscPosPrinter class in my printer program. In particular the Serial1_Connected event.
Hi Agraham

I am not winning in this battle. Your Printer program also gives me an error message. I tried the other BT examples on the Forum, but when I try to run them, the Android gives me a message of "App Not Loaded"'.

Please have a look at my Code.

Here is my Bluetooth Class:

B4X:
[/
Sub Class_Globals
    'Bluetooth
    Public Serial As Serial
    Public Admin As BluetoothAdmin
    Public AStream As AsyncStreams
    Public FoundDevices As List
    Type NameAndMac (Name As String, Mac As String)
    Dim nm As NameAndMac
    Public ReadData As String
'    Private rp As RuntimePermissions
    Public BluetoothState, ConnectionState As Boolean
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    Try
        Admin.Initialize("admin")
        Serial.Initialize("serial")
'        If AStream.IsInitialized Then AStream.Close
        Admin.Enable
        If Admin.IsEnabled = False Then
            If Admin.Enable = False Then
                ToastMessageShow("Error Enabling Bluetooth...", True)
            End If
        Else
            BluetoothState = True
        End If
    Catch
        Log(LastException)
    End Try
End Sub


Private Sub Admin_StateChanged (NewState As Int, OldState As Int)
    Log("state changed: " & NewState)
    BluetoothState = NewState = Admin.STATE_ON
    NotifyOfStateChanged
End Sub

Private Sub NotifyOfStateChanged
'    For Each Target In Array(Main, ChatActivity)
'        CallSub(Target, "UpdateState")
'    Next
End Sub

Public Sub Connect As Boolean
    Dim PairedDevices As Map
    Dim A, A1 As String
  
    PairedDevices = Serial.GetPairedDevices
    Dim l As List
    l.Initialize
    For i = 0 To PairedDevices.Size - 1
        l.Add(PairedDevices.GetKeyAt(i))
    Next
    Dim Res As Int
    Res = InputList(l, "Select Instrument", -1) 'show list with paired devices
    If Res <> DialogResponse.CANCEL Then
        Serial.Connect(PairedDevices.Get(l.Get(Res))) 'convert the name to mac address
      
        A = PairedDevices.Get(l.Get(Res))
        A1 = PairedDevices.GetKeyAt(Res)
        Instruments(A, A1)
      
        Return True
    Else
        Return False
    End If
End Sub

Private Sub Serial_Connected (Success As Boolean)
    Log("connected: " & Success)
    CallSub2(Main, "AfterConnect", Success) 'allow the activity to hide the progress dialog
    ConnectionState = Success
    If Success = False Then
        Log(LastException.Message)
        ToastMessageShow("Error connecting: " & LastException.Message, True)
        ProgressDialogHide
    Else
        If AStream.IsInitialized Then AStream.Close
        'prefix mode! Change to non-prefix mode if communicating with non-B4X device.
        AStream.Initialize(Serial.InputStream, Serial.OutputStream, "astream")
'        StartActivity(ChatActivity)
    End If
    NotifyOfStateChanged
End Sub

Sub Instruments(A As String, A1 As String)
    If CGlobals.li = 0 Then
        CGlobals.DF(24)=A1
        CGlobals.DF(25)=1
        CGlobals.DF(26)=A
        Msgbox2Async("Your Level Has Been Connected To " & A1, "Connected", "OK", "", "", Null,False)
    Else If CGlobals.Li=1 Then
        'Total Station
        CGlobals.DF(5)=A1
        CGlobals.DF(6)=1
        CGlobals.DF(7)=A
        Msgbox2Async("Your TS Has Been Connected To " & A1, "Connected", "OK", "", "", Null,False)
    Else If CGlobals.Li=2 Then
        'GPS
        If CGlobals.BaseChecked=1 Then
            CGlobals.DF(33)=A1
            CGlobals.DF(34)=1
            CGlobals.DF(35)=A
            Msgbox2Async("Your GPS Base Has Been Connected To " & A1, "Connected", "OK", "", "", Null,False)
        Else If CGlobals.RoverChecked=1 Then
            CGlobals.DF(52)=A1
            CGlobals.DF(53)=1
            CGlobals.DF(54)=A
            Msgbox2Async("Your GPS Rover Has Been Connected To " & A1, "Connected", "OK", "", "", Null,False)
        End If
    End If
End Sub

Public Sub ConnectTo (Device As NameAndMac)
    Try
        Serial.Connect(Device.Mac)
    Catch
        Log(LastException)
    End Try
End Sub

Public Sub Disconnect
    If AStream.IsInitialized Then AStream.Close
    Serial.Disconnect
End Sub

Public Sub Disable
    Admin.Disable
End Sub

'Public Sub Enable
'    Admin.Enable
'End Sub

Public Sub SearchForDevices As Boolean
    Return Admin.StartDiscovery
End Sub

Public Sub Admin_DiscoveryFinished
    CallSub(Parameter, "DiscoverFinished")
End Sub

Public Sub Admin_DeviceFound (Name As String, MacAddress As String)
    If Name<>"" And MacAddress<>"" Then
        Dim nm As NameAndMac
        nm.Name = Name
        nm.Mac = MacAddress
        FoundDevices.Add(nm)
    End If
End Sub

Public Sub AfterSuccessfulConnection
    If AStream.IsInitialized Then AStream.Close
    'prefix mode! Change to non-prefix mode if communicating with non-B4X device.
'    AStream.Initialize(Serial.InputStream, Serial.OutputStream, "AStream")
End Sub

Public Sub StopReading(A As String)
    Serial.StopListening
End Sub

Public Sub ReadDeviceDataAsync (Buffer() As Byte)
    ReadData=BytesToString(Buffer, 0, Buffer.Length, "UTF8")
End Sub

Public Sub SendDataToDevice(A As String)
    AStream.Write(A.GetBytes("utf8"))
End Sub

Public Sub CloseConnection
  
End Sub

Public Sub ClearOutputData
  
End Sub

Public Sub ClearBuffer
  
End Sub

Public Sub Pair
    Serial.Listen
  
'    Dim StartingIntent As String
'  
'    If StartingIntent.Action = "ACTION_PAIRING_REQUEST" Then
'        Dim jo As JavaObject = StartingIntent
'        Dim device As JavaObject = jo.RunMethod("getParcelableExtra", Array("android.bluetooth.device.extra.DEVICE"))
'        device.RunMethod("setPairingConfirmation", Array(True))
'    End If
End Sub
]

In my "Parameters" Activity, I scan for Devices and then try to connect.

B4X:
[/

Sub Paired_Click
    Dim success As Boolean = BT.Connect
    If success = False Then
        ToastMessageShow("Cannot Connect.", True)
    Else
        ToastMessageShow("Connected.", True)
    End If
End Sub

Sub FindDevice
    CLV.Clear
    BT.FoundDevices.Initialize
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No Permission...", False)
        Return
    End If
    Dim success As Boolean = BT.SearchForDevices
    If success = False Then
        ToastMessageShow("Error Starting Discovery Process.", True)
    Else
        ProgressDialogShow2("Searching For Devices...", True)
    End If
End Sub

Sub DiscoverFinished
    Try
        ProgressDialogHide
        If BT.FoundDevices.Size = 0 Then
            ToastMessageShow("No Device Found.", True)
        Else
            For Each nm As NameAndMac In BT.FoundDevices
                CLV.AddTextItem($"${nm.Name}"$, nm.Name)
            Next
        End If
    Catch
        Log(LastException)
    End Try
End Sub

Sub CLV_ItemClick (Index As Int, Value As Object)
    Try
        Dim DeviceCon As NameAndMac = BT.FoundDevices.Get(Index)
        ProgressDialogShow2("Trying to connect to: " & DeviceCon.Name, True)
        BT.ConnectTo(DeviceCon)
        Wait For Serial_Connected (Success As Boolean)
        ProgressDialogHide
        If Success = False Then
            Log(LastException.Message)
            Msgbox2Async("Error Connecting", "Cannot Connect To Instument", "OK", "", "", Null,False)
        Else
            BT.AfterSuccessfulConnection
            Instruments(DeviceCon)
        End If
    Catch
        Log(LastException)
    End Try
End Sub

Sub Instruments(A As NameAndMac)
    If Dumpy.Checked = True Then
        CGlobals.DF(24)=A.Name
        CGlobals.DF(25)=1
        CGlobals.DF(26)=A.Mac
        Msgbox2Async("Your Level Has Been Connected To " & A.Name, "Connected", "OK", "", "", Null,False)
    Else If TS.Checked=True Then
        'Total Station
        CGlobals.DF(5)=A.Name
        CGlobals.DF(6)=1
        CGlobals.DF(7)=A.Mac
        Msgbox2Async("Your TS Has Been Connected To " & A.Name, "Connected", "OK", "", "", Null,False)
    Else If GPS.Checked=True Then
        'GPS
        If Base.Checked=True Then
            CGlobals.DF(33)=A.Name
            CGlobals.DF(34)=1
            CGlobals.DF(35)=A.Mac
            Msgbox2Async("Your GPS Base Has Been Connected To " & A.Name, "Connected", "OK", "", "", Null,False)
        Else If Rover.Checked=True Then
            CGlobals.DF(52)=A.Name
            CGlobals.DF(53)=1
            CGlobals.DF(54)=A.Mac
            Msgbox2Async("Your GPS Rover Has Been Connected To " & A.Name, "Connected", "OK", "", "", Null,False)
        End If
    End If
End Sub

]

I find all my Devices, but I cannot connect. Even if I pair outside my Program and I list all the paired Devices, I cannot connect to anyone.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Your comments are short of concrete details so it is difficult to help as you are not detailing where it is failing. Tell me the detail of what you have tried and the manner of failure.. You say my printer program also gives an error message - what is the message?

If you pair your instrument outside the app does it appear as a choice in my printer program? You code seems a bit complicated. It should be trivial to strip out my simpler printer class and implement a simple terminal to talk to the instrument. You might need to add PERMISSION_ACCESS_FINE_LOCATION if you change the target SDK to a later one.
 
Upvote 0

Terradrones

Active Member
Your comments are short of concrete details so it is difficult to help as you are not detailing where it is failing. Tell me the detail of what you have tried and the manner of failure.. You say my printer program also gives an error message - what is the message?

If you pair your instrument outside the app does it appear as a choice in my printer program? You code seems a bit complicated. It should be trivial to strip out my simpler printer class and implement a simple terminal to talk to the instrument. You might need to add PERMISSION_ACCESS_FINE_LOCATION if you change the target SDK to a later one.
Hi Agraham

In the next code I search for devices and list them. This works correctly.

B4X:
[/

Sub FindDevice
    CLV.Clear
    BT.FoundDevices.Initialize
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No Permission...", False)
        Return
    End If
    Dim success As Boolean = BT.SearchForDevices
    If success = False Then
        ToastMessageShow("Error Starting Discovery Process.", True)
    Else
        ProgressDialogShow2("Searching For Devices...", True)
    End If
End Sub

Sub DiscoverFinished
    Try
        ProgressDialogHide
        If BT.FoundDevices.Size = 0 Then
            ToastMessageShow("No Device Found.", True)
        Else
            For Each nm As NameAndMac In BT.FoundDevices
                CLV.AddTextItem($"${nm.Name}"$, nm.Name)
            Next
        End If
    Catch
        Log(LastException)
    End Try
End Sub
]

Next I click in the list on the Device that I want to connect to:

[CODE=b4x][/

Sub CLV_ItemClick (Index As Int, Value As Object)
    Try
        Dim DeviceCon As NameAndMac = BT.FoundDevices.Get(Index)
        ProgressDialogShow2("Trying to connect to: " & DeviceCon.Name, True)
        BT.ConnectTo(DeviceCon)
        Wait For Serial_Connected (Success As Boolean)
        ProgressDialogHide
        If Success = False Then
            Log(LastException.Message)
            Msgbox2Async("Error Connecting", "Cannot Connect To Instument", "OK", "", "", Null,False)
        Else
            BT.AfterSuccessfulConnection
            Instruments(DeviceCon)
        End If
    Catch
        Log(LastException)
    End Try
End Sub

]

I never get a "Success = True""

And the Error that I get is:

java.io.IOException: read failed, socket might closed or timeout, read ret: -1

If I go the other route and Display the paired Devices, I use this code:

[CODE=b4x][/
Sub Paired_Click
    Dim success As Boolean = BT.Connect
    If success = False Then
        ToastMessageShow("Cannot Connect.", True)
    Else
        ToastMessageShow("Connected.", True)
    End If
End Sub
]

It gives me "Succes"

But in my BT Class:

[CODE=b4x][/

Public Sub Connect As Boolean
    Dim PairedDevices As Map
    Dim A, A1 As String
   
    PairedDevices = Serial.GetPairedDevices
    Dim l As List
    l.Initialize
    For i = 0 To PairedDevices.Size - 1
        l.Add(PairedDevices.GetKeyAt(i))
    Next
    Dim Res As Int
    Res = InputList(l, "Select Instrument", -1) 'show list with paired devices
    If Res <> DialogResponse.CANCEL Then
        Serial.Connect(PairedDevices.Get(l.Get(Res))) 'convert the name to mac address
       
        A = PairedDevices.Get(l.Get(Res))
        A1 = PairedDevices.GetKeyAt(Res)
        Instruments(A, A1)
       
        Return True
    Else
        Return False
    End If
End Sub

Private Sub Serial_Connected (Success As Boolean)
    Log("connected: " & Success)
    CallSub2(Main, "AfterConnect", Success) 'allow the activity to hide the progress dialog
    ConnectionState = Success
    If Success = False Then
        Log(LastException.Message)
        ToastMessageShow("Error connecting: " & LastException.Message, True)
        ProgressDialogHide
    Else
        If AStream.IsInitialized Then AStream.Close
        'prefix mode! Change to non-prefix mode if communicating with non-B4X device.
        AStream.Initialize(Serial.InputStream, Serial.OutputStream, "astream")
'        StartActivity(ChatActivity)
    End If
    NotifyOfStateChanged
End Sub

]

It returns a "False"

With the same error code:

java.io.IOException: read failed, socket might closed or timeout, read ret: -1
 
Upvote 0
Top