Android Question How do i call a Sub in B4XMainPage from Starter?


I have moved forward and almost got my app to basically work. However I am porting the BLE scan example
to a B4XPages type application. I have run into an issue trying to get the BLE2 library functions/events to callback
to the Subs that were in the old "Main" module but are now in "B4XMainPage" module.
Here is the BLE2 handler for data available event in Starter with my commented out line to try to call the function:
BLE Event Stub for State Changed:
Sub BLEman_StateChanged (State As Int)
    LogColor("BLEman StateChanged = "&State,Colors.Green)
    Select State
            currentStateText = "POWERED OFF"
        Case BLEman.STATE_POWERED_ON
            currentStateText = "POWERED ON"
            currentStateText = "UNSUPPORTED"
    End Select
    currentState = State
    B4XPages.MainPage.StateChanged( State )
End Sub

and the function it is trying to call which is in B4XMainPage:

BLE2 Event Sub:
Sub StateChanged ( state As Int)
  Log("in StateChanged..."&state)
    lblState.Text = Starter.currentStateText
    If Starter.connected Then
        lblDeviceStatus.Text = "Connected: " & Starter.ConnectedName
        lblDeviceStatus.Text = "Not Connected"
    End If
    btnDisconnect.Enabled = Starter.connected
    btnScan.Enabled = Not(Starter.connected)
    pbReadData.Visible = False
    pbScan.Visible = False
    btnReadData.Enabled = Starter.connected
    btnScan.Enabled = (Starter.currentState = Starter.BLEman.STATE_POWERED_ON) And Starter.connected = False
End Sub

Problem is just after compile and sending to the device (B4Xbridge) it tosses this:

Runtime Java error trail sub set::
*** Debugger waiting for connection (1) ***
After accept
*** Service (starter) Create ***
BLEman started...
** Service (starter) Start **
BLEman StateChanged = 12
Error occurred on line: 15 (B4XPages)
java.lang.ClassCastException: java.lang.Object cannot be cast to FW6.App.b4xpagesmanager
    at FW6.App.b4xpages._getmanager(
    at FW6.App.b4xpages._mainpage(
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(
    at anywheresoftware.b4a.BA.raiseEvent(
    at anywheresoftware.b4a.objects.BleManager2$1$
    at android.os.Handler.handleCallback(
    at android.os.Handler.dispatchMessage(
    at android.os.Looper.loop(
    at java.lang.reflect.Method.invoke(Native Method)
null: 59
java.lang.NullPointerException: Attempt to read from field 'java.lang.String$RemoteObject.className' on a null object reference

A note that the calls from Starter B4XPages.MainPage.DoDataAvailable( ServiceId, Characteristics ) works
as it did in the original example.
Sub BLEman_DeviceFound (Name As String, Id As String, AdvertisingData As Map, RSSI As Double) also works well
as it did in the activity example it came from.
I just can't get the B4XPages.MainPage.StateChanged( State ) call back to work, won't run, crashes Java?

I added a parameter to StateChanged thinking that might be it? No change. Of the 3 call back functions
the two with parameters work, this one with out a parameter crashes java at runtime.

That's it, hope I'm clear on it. I'll attache the project files too.

Thanks in advance,


    78.3 KB · Views: 46


I have figured out one thing, the start up of the BLE2 manager service immediately invokes
a 'state changed' event. At that moment the B4XMainPage has not been setup so it bombs.
I am messing with a flag to gate off the call back to the MainPage handler until it is started.
The two call backs that work do so because by that time I have the MainPage up and have
pressed buttons to cause the action. Sorting out start up seems to be my issue. Maybe delay
starting the BLEmanager until things in MainPage are setup would be another way.
Is there an easier or cleaner way for orchestrating this start up sequence that I'm not seeing?
Upvote 0


Well-Known Member
Licensed User
Longtime User
1. Create a new service called BleService and move all BLE related code from Starter service to the new service.
2. Call StartService(BleService) at the end of B4XPage_Create
Upvote 0


1. Create a new service called BleService and move all BLE related code from Starter service to the new service.
2. Call StartService(BleService) at the end of B4XPage_Create
Great answer, thanks a ton. I know once I get an app. up using B4X IDE I'll be there and can help others too.
I did exactly what you suggested and added a 'new service' module to my project and swept the BLE2 code into that. It wasn't obvious that the BLE2 module usage needed to be in a 'service' module and that I could do that in an additional 'service' module after program start and calling to initialize it.

I didn't see much in the 'booklets' on 'services' vs 'activities' vs 'Pages' to really understand their full relationship at runtime. This knowledge comes with practice and help from others. I sort of thought there could be only one 'service' so you had to do it all in there as far as peripheral I/O.

There are lots of great booklets but not one that details what an overall Android program could look like as far as the 'modules' are concerned as well as general rules for the required modules and your own additional ones. Cheers!
Upvote 0