Android Question msgbox2Async in class event

Yannick Proulx

Member
Licensed User
Hi Guys,
I'm trying to display a message to the user from within a event in a class and I keep getting the following error .
How do I send a message to the user from within an event.(BTW toastmessageshow works)

Thanks for you help!

B4X:
Error occurred on line: 101 (test)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.ref.Reference.get()' on a null object reference
    at anywheresoftware.b4a.keywords.Common.Msgbox2Async(Common.java:475)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:755)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:345)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
    at anywheresoftware.b4a.BA$2.run(BA.java:360)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6688)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
 

Yannick Proulx

Member
Licensed User
Can you post the relevant code?

Where is this class instance initialized? It must have an activity context.

Hi Erel,

I Initialize the class in my Starter service so it is accessible by every activity.
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Public kvs As KeyValueStore
    Public MAC_ADDRESS_Scanner As String = "MAC ADDRESS"
    Dim t As test'--------------------------this is the class with the event that try to send message to user
End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.
    t.Initialize
End Sub

then in my main activity, I Call a sub in my Class named ConnectSerial witch initialize Serial connection, When Serial return it raise the event Serial1_Connected below.(This part is working)
if connection failed then I would like to send a message to the user where ever he is in the app.
Here is the problematic sub in my class code.
B4X:
Sub Class_Globals
    Dim serial1 As Serial 'Bluetooth Serial Port
    Dim AStream As AsyncStreams 'ASyncronous Streams returned by the scanner once connected
    Dim et As Object 'EditText Object transferred by requesting Activity, used to return value to EditText on scanner return

End Sub

'Event Raised after we try to connect to Serial BT
'If connection succed then success boolean will return true
'we then can connect the async Stream to that Serial port
'if Success return False then we notify user that connection Failed and wait for his choice
Sub Serial1_Connected (Success As Boolean)
    If Success = True Then
        ToastMessageShow("Scanner Connecté",False)
        Log("Scanner is now connected. Waiting for data...")
        AStream.Initialize(serial1.InputStream, serial1.OutputStream, "AStream")
    Else
      
        If Starter.kvs.ContainsKey(Starter.MAC_ADDRESS_Scanner) Then
            Log("Trying to connect to mac address : " & Starter.kvs.Get(Starter.MAC_ADDRESS_Scanner))
            If Starter.firsttry Then
                Starter.firsttry = False 'set to false has we have first try it once
                ToastMessageShow("Tentative de connexion au scanner...",True)'----------------------------- toast message works
                serial1.Connect(Starter.kvs.Get(Starter.MAC_ADDRESS_Scanner)) 'convert the name to mac address and connect
            Else
    Log("Ask user what he wanna do as we are not able to connect to the actual scanner")
                  
    Msgbox2Async("Connection Impossible, Verifiez que le scanner est allumé. Voulez vous réessayer ?","Erreur de connexion","Oui","Annuler","Choisir un autre scanner",Null,False)'----------------------------This line gives me the error I post erlier.
    Wait For Msgbox_Result (result As Int)
    Select Case result
                  
        Case DialogResponse.POSITIVE
            Log("Trying to reconnect Scanner once again...")
'            serial1.Connect(Starter.kvs.Get(Starter.MAC_ADDRESS_Scanner)) 'convert the name to mac address and connect
            ConnectSerial 'Trying to reconnect
           
                                      
        Case DialogResponse.NEGATIVE
            Log("User want to change Scanner MAC Address")
            ShowPairedDevices
          
                      
        Case DialogResponse.CANCEL
            Log("Cancel selected so return")
            Starter.kvs.Remove(Starter.MAC_ADDRESS_Scanner) '--------------------------------------------------debug only
             Return
                              
    End Select
  End If
          
        Else
            Log("As no scanner already connected ... ask user to choose a scanner")
            ShowPairedDevices
        End If
      
    End If
End Sub


I found a way to overcome this. I create an Activity dedicate to message the user and call the following sub. But I don't find it pretty... It overcome the actual activity with the msgbox and then when user answer the question I call activity.finish to close this activity. Is there a better way to do this.
B4X:
Sub msgboxReply
    Activity.Title = "Problème de connexion"
    Activity.Color = Colors.Red
    Log("Ask user what he wanna do as we are not able to connect to the actual scanner")
                  
    Msgbox2Async("Connection Impossible, Verifiez que le scanner est allumé. Voulez vous réessayer ?","Erreur de connexion","Oui","Annuler","Choisir un autre scanner",Null,False)
    Wait For Msgbox_Result (result As Int)
    Select Case result
                  
        Case DialogResponse.POSITIVE
            Log("Trying to reconnect Scanner once again...")
'            Starter.t.serial1.Connect(Starter.kvs.Get(Starter.MAC_ADDRESS_Scanner)) 'convert the name to mac address and connect
            Starter.t.ConnectSerial
            Activity.Finish
                                      
        Case DialogResponse.NEGATIVE
            Log("User want to change Scanner MAC Address")
            Starter.t.ShowPairedDevices
          
                      
        Case DialogResponse.CANCEL
            Log("Cancel selected so return")
            Starter.kvs.Remove(Starter.MAC_ADDRESS_Scanner) '--------------------------------------------------debug only
            Activity.Finish
            Return
                              
    End Select
End Sub

Thanks for your help once again.
 
Upvote 0

Yannick Proulx

Member
Licensed User
If you initialize the class in the starter service then it has a service context and it cannot show any UI (except of toast messages).
Hi Erel,
Thanks for your reply.

can I still declare it in my starter service but initialize it into my main (start up activity)? will I be able to show UI?
 
Upvote 0

Yannick Proulx

Member
Licensed User
It will not work. If the class instance is public then it cannot have an Activity context.

You should raise an event from the class instance (CallSub) and handle it in the activity. Show the message in the activity sub.

Ok so my dedicated activity is one of the way to achive that as I don't want to copy those sub in every Activity .... ok good so I will keep it that way

Thanks for your help
 
Upvote 0
Top