Android Question Creating a Bluetooth Classic paired device listbox

doodooronron

Member
Licensed User
I'm new to B4A and for the past week have been trying to get InputListAsync working on my first attempt at coding an app.

The BT connection is to a Classic Bluetooth SPP module in transparent mode.

I come from AppInventor2, where the result was achieved with just these building blocks.

BTlist.PNG


The code below was cobbled together from other contributors (Thanks go to them!).
I'm slowly getting to understand more and more, but still cannot get a list of paired devices to display so that I can select one to connect to.

This is from the Starter module. The errors are on line 37 when compiled and line 33 when run on the device.

B4X:
Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals
    Private serial As Serial
    Private admin As BluetoothAdmin
    Private ast As AsyncStreamsText
    Public Connected = False As Boolean
    Public Connecting = False As Boolean
    Public TryToConnect = False As Boolean
    Public Scanning = False As Boolean
    Public Mac = "" As String
    Public Devices As Map
End Sub

Sub Service_Create
    serial.Initialize("serial")
    admin.Initialize("admin")
    Devices.Initialize
End Sub

Public Sub Connect
    Dim PairedDevices As Map
    PairedDevices = serial.GetPairedDevices
    Dim l As List
    l.Initialize
    For i = 0 To PairedDevices.Size - 1
        l.Add(PairedDevices.GetKeyAt(i))
    Next
 
    InputListAsync(l, "Choose device", -1, False)    'show list with paired devices
    Wait For InputList_Result (res As Int)
    If res <> DialogResponse.CANCEL Then
        serial.Connect(PairedDevices.Get(l.Get(res))) 'convert the name to mac address and connect
    End If
    TryToConnect = False
    Connecting = True
    CallSub(Main, "SetState")
End Sub

Public Sub AfterConnect (Success As Boolean)
    ProgressDialogHide
End Sub

Sub Admin_DeviceFound (Name As String, MacAddress As String)
    Devices.Put(MacAddress, Name)
    ProgressDialogShow($"Searching for devices (${Devices.Size} devices found)"$)
End Sub

Private Sub admin_DiscoveryFinished
    If Connecting = False Then
        TryToConnect = False
        CallSub(Main, "SetState")
    End If
End Sub

Private Sub Serial_Connected (Success As Boolean)
    If Success Then
        If ast.IsInitialized Then ast.Close
        ast.Initialize(Me, "Ast", serial.InputStream, serial.OutputStream)
        Log("Connected")
        Connected = True
    Else
        Log(LastException)
    End If
    Connecting = False
    CallSub(Main, "SetState")
End Sub

Public Sub SendMessage(Buffer As String)
    Buffer = "#" & Buffer
    ast.astreams.Write(Buffer.GetBytes("UTF8"))
    ast.astreams.Write(Array As Byte(10)) 'end of line character. AsyncStreamsText will cut the message here
End Sub

Private Sub ast_NewText (Text As String)
    CallSub2(Main, "MessageFromDevice", Text)
End Sub

Private Sub ast_Terminated
    Connected = False
    CallSub(Main, "SetState")
End Sub

Sub Service_Start (StartingIntent As Intent)

End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

Logger connected to: samsung GT-I9300
--------- beginning of /dev/log/main
Copying updated assets files (1)
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
BT SPEAKER
DESKTOP-9KS9H4O
TABLET
TiaPapasgarden
Desire HD
WellRedCoronet
Error occurred on line: 37 (Starter)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.keywords.Common.CallSubDebug(Common.java:1050)
at b4a.HC05LightDimmer.main._btnscan_click(main.java:534)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:4211)
at android.view.View$PerformClick.run(View.java:17267)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:336)
at anywheresoftware.b4a.debug.Debug.CallSubNew(Debug.java:282)
... 26 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
... 27 more
Caused by: java.lang.NullPointerException
at anywheresoftware.b4a.keywords.Common.InputListAsync(Common.java:553)
at b4a.HC05LightDimmer.starter$ResumableSub_Connect.resume(starter.java:244)
at b4a.HC05LightDimmer.starter._connect(starter.java:163)
... 30 more
** Activity (main) Pause, UserClosed = true **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **
Error occurred on line: 33 (Starter)
java.lang.NullPointerException
at anywheresoftware.b4a.keywords.Common.InputListAsync(Common.java:553)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
at b4a.HC05LightDimmer.starter._connect(starter.java:161)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
at anywheresoftware.b4a.debug.Debug.CallSubNew(Debug.java:282)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.keywords.Common.CallSubDebug(Common.java:1050)
at b4a.HC05LightDimmer.main._btnscan_click(main.java:534)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:4211)
at android.view.View$PerformClick.run(View.java:17267)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Pause, UserClosed = true **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **
Error occurred on line: 33 (Starter)
java.lang.NullPointerException
at anywheresoftware.b4a.keywords.Common.InputListAsync(Common.java:553)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
at b4a.HC05LightDimmer.starter._connect(starter.java:161)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
at anywheresoftware.b4a.debug.Debug.CallSubNew(Debug.java:282)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.keywords.Common.CallSubDebug(Common.java:1050)
at b4a.HC05LightDimmer.main._btnscan_click(main.java:534)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:4211)
at android.view.View$PerformClick.run(View.java:17267)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)

Any and all suggestions welcome.

Thanks
 
Last edited:

doodooronron

Member
Licensed User
Thanks Erel.

The chat example scans for available devices every time I want to connect which takes quite a long time and, being Bluetooth, is fairly hit and miss. It also seems to have difficulty finding a device after the first time it is paired.

Is there a way to load and use the list of already-paired devices from the Android BT data instead of scanning every time?

I also get "Connection is broken" every time I try to connect. Is this a consequence of trying to connect to a device which is not running the chat app also?

The device I am trying to connect to sends a packet of data every second.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Is there a way to load and use the list of already-paired devices from the Android BT data instead of scanning every time?
Yes. Use Serial.GetPairedDevices.

I also get "Connection is broken" every time I try to connect. Is this a consequence of trying to connect to a device which is not running the chat app also?
Yes.

Also make sure not to initialize AsyncStreams in prefix mode, in this case.
 
Upvote 0
Top