Italian B4XPages - (scarso) Tutorial in italiano

Fulvio75

Well-Known Member
Licensed User
Invece di usare un modulo, usa il service "Starter" e risolvi il problema.
e no.... ho la necessità di chiamare l'inizializzazione in diversi punti del codice a seconda di quello che succede, tranne all'avvio dell'applicazione che deve partire la lettura della centralina della macchina oppure stopparsi in determinati casi, è lunga da spiegare:) se no non funziona più
 

LucaMs

Expert
Licensed User
Longtime User
ho la necessità di chiamare l'inizializzazione in diversi punti del codice
Credo che a te serva che gli eventi scattino in diverse "schermate", non che tu debba inizializzare l'oggetto BT in vari punti (schermate); no?

Quindi sia che usi lo Starter con N Activity, sia che usi le B4Pages, dovresti avere un'unica inizializzazione, gli eventi nel punto in cui lo fai (direttamente la Main o nella B4XMainPage), e poi "deleghi" (giri) gli eventi all'Activity o pagina correntemente visibile.
 

Fulvio75

Well-Known Member
Licensed User
Credo che a te serva che gli eventi scattino in diverse "schermate", non che tu debba inizializzare l'oggetto BT in vari punti (schermate); no?

Quindi sia che usi lo Starter con N Activity, sia che usi le B4Pages, dovresti avere un'unica inizializzazione, gli eventi nel punto in cui lo fai (direttamente la Main o nella B4XMainPage), e poi "deleghi" (giri) gli eventi all'Activity o pagina correntemente visibile.
Uso solo una Activity in questo progetto perché la visualizzazione è una sola poi il panel lo uso per le impostazioni.
Come faccio a girare l'evento generato dalla Activity alle altre?
Una volta che apro una seconda Activity l'evento della connessione non funziona più, ovvero quando gli arrivano i dati alla connessione essa se mi trovo in un'altra Activity non genera astream_new
 

LucaMs

Expert
Licensed User
Longtime User
Uso solo una Activity in questo progetto perché la visualizzazione è una sola poi il panel lo uso per le impostazioni.
Come faccio a girare l'evento generato dalla Activity alle altre?
Una volta che apro una seconda Activity l'evento della connessione non funziona più, ovvero quando gli arrivano i dati alla connessione essa se mi trovo in un'altra Activity non genera astream_new
Nel mio post precedente, intendevo dire che se non vuoi usare le B4XPage (che facilitano un bel po' di cose ma quasi tutto si può fare ugualmente con le Activity e basta), dovresti usare il modulo di servizio Starter.

Dichiari una variabile BT nel servizio, la inizializzi e scrivi i suoi eventi in quello.
Quando nello Starter dovesse scattare ad esempio l'evento:
B4X:
'NELLO STARTER.
Sub Process_Globals
    Private manager As BleManager2
End Sub

Sub Service_Create
    manager.Initialize("Manager")
End Sub

Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
    ' Chiami una Sub dell'Activity in primo piano, ovvero "deleghi" a questa l'operazione che devi eseguire.
     CallSubDelayed2(getCurrentActivity, "DataAvailable", ServiceId, Characteristics)
End Sub

Sub getCurrentActivity As Activity
   Dim r As Reflector
   r.Target = r.GetActivityBA
   Return r.GetField("vg")
End Sub

B4X:
'IN OGNI ACTIVITY CHE DEVE POTER "INTERCETTARE" GLI EVENTI BT.
Sub DataAvailable(ServiceId As String, Characteristics As Map)
'
End Sub

' Stessa cosa per gli altri eventi BT.
 
Last edited:

Fulvio75

Well-Known Member
Licensed User
Nel mio post precedente, intendevo dire che se non vuoi usare le B4XPage (che facilitano un bel po' di cose ma quasi tutto si può fare ugualmente con le Activity e basta), dovresti usare il modulo di servizio Starter.

Dichiari una variabile BT nel servizio, la inizializzi e scrivi i suoi eventi in quello.
Quando nello Starter dovesse scattare ad esempio l'evento:
B4X:
'NELLO STARTER.
Sub Process_Globals
    Private manager As BleManager2
End Sub

Sub Service_Create
    manager.Initialize("Manager")
End Sub

Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
    ' Chiami una Sub dell'Activity in primo piano, ovvero "deleghi" a questa l'operazione che devi eseguire.
     CallSubDelayed2(getCurrentActivity, "DataAvailable", ServiceId, Characteristics)
End Sub

Sub getCurrentActivity As Activity
   Dim r As Reflector
   r.Target = r.GetActivityBA
   Return r.GetField("vg")
End Sub

B4X:
'IN OGNI ACTIVITY CHE DEVE POTER "INTERCETTARE" GLI EVENTI BT.
Sub DataAvailable(ServiceId As String, Characteristics As Map)
'
End Sub

' Stessa cosa per gli altri eventi BT.
Ok quindi BT e Connection se dichiarato in starter l'evento si genera sempre anche con altre activity aperte, questo non lo sapevo
Grazie
 

Fulvio75

Well-Known Member
Licensed User
Ho fatto delle prove...
Ora la soluzione è perfetta, non potendo convertire tutto in B4APages:
se creo un servizio diverso da start e scrivo li il codice di disconnessione ELM327 ,BT ecc.ecc. e lo chiamo in Pause con StartService..... l'app va in pausa e il servizio fa tutto anche con app in pausa risolvendo alcuni problemi, ora... il servizio che chiamo in pausa alla fine del codice di quello che ho bisogno che debba fare devo aggiungerci qualche cosa per terminarlo perchè può dare problemi oppure esegue il codice e stop
 

Fulvio75

Well-Known Member
Licensed User
Pero su pause se faccio partire il servizio ho notato che il codice al suo interno funziona, le chiamate ai moduli funzionano e il codice viene eseguito, se faccio callsub per chiamare una sub in una Activity il codice di questa sub non viene eseguito.
Mi sa che dai prossimi progetti passerò alle Pages ? ?‍♂️
 

Fulvio75

Well-Known Member
Licensed User
Se l'activity non è visibile, perchè dovrebbe essere eseguito il Sub?
Salva quello che vuoi visualizzare in una variabile e quando l'activity è nuovamente visibile, chiami il Sub.
Callsub è per eseguire del codice che mi serve per disabilitare il media player se in esecuzione
 

LucaMs

Expert
Licensed User
Longtime User
Credo, mi pare, mi sembra, ho il vago sospetto che... siamo leggermente fuori tema ?

La tua app pare piuttosto complicata, quindi apri un thread proprio per questa.
Non ho ben capito perché hai bisogno di due "servizi".

Per chiamare una Sub di un'Activity da un servizio, dovresti usare CallSubDelayed (una delle 3 versioni). A differenza delle B4XPages (!!!), il comando verrà accodato (messo in coda - queue) ed eseguito solo quando l'Activity sarà riportata in foreground (visibile). E non è nemmeno certo che non si perda!

Se ricordo bene (ormai uso solo le B4XPages), se c'è già un'Activity in primo piano e da un servizio chiami una Sub di un'altra, sempre con CallSubDelayed, questa seconda viene portata in foreground.
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
@mcqueccu sta iniziando a pubblicare dei video su questo argomento (B4XPages).
Potete guardarli facendogli mostrare i sottotitoli (generati "al volo") in italiano.
https://www.b4x.com/android/forum/threads/b4xpages-video-tutorial-series.157404/

(Non che me ne voglia lavare le mani, eh ?, ma visto che lo fa, vale la pena guardarli)
Volendo, passate subito a questo, che in un certo senso si potrebbe definire "un corso più avanzato", in quanto mostra direttamente lo sviluppo di un progetto B4A-B4XPages.
https://www.b4x.com/android/forum/t...-building-membership-registration-app.157407/
 
Last edited:

Fulvio75

Well-Known Member
Licensed User
Iniziato progetto B4XPages... già incominciano i problemi:

ho delle view ImageView nel layout MainPage

e la dichiarazione di queste View sono in B4XMainPage:

B4X:
Sub Class_Globals
    
    Private Root As B4XView
    Private xui As XUI   
    
    'Stato applicazione
    Private img1 As ImageView
    Private img2 As ImageView
    Private img3 As ImageView
    
    'Pannello di attesa
    Private pnlWaiting As Panel
    Private lblWaiting As Label
    
End Sub

ERRORE

... 45 more
Error occurred on line: 34 (B4XMainPage)
java.lang.RuntimeException: java.lang.RuntimeException: Object should first be initialized (ImageView).
Did you forget to call Activity.LoadLayout?
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:155)
at anywheresoftware.b4a.objects.PanelWrapper.LoadLayout(PanelWrapper.java:134)
at anywheresoftware.b4a.objects.B4XViewWrapper.LoadLayout(B4XViewWrapper.java:329)
at java.lang.reflect.Method.invoke(Native Method)
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.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
at af.software.ecureader.b4xmainpage._b4xpage_created(b4xmainpage.java:55)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:318)
at anywheresoftware.b4a.debug.Debug.CallSubNew2(Debug.java:285)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.keywords.Common.CallSubDebug2(Common.java:1087)
at af.software.ecureader.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:1074)
at af.software.ecureader.b4xpagesmanager._showpage(b4xpagesmanager.java:431)
at af.software.ecureader.b4xpagesmanager._addpage(b4xpagesmanager.java:251)
at af.software.ecureader.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:265)
at af.software.ecureader.b4xpagesmanager._initialize(b4xpagesmanager.java:171)
at af.software.ecureader.main._activity_create(main.java:422)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)

perchè?
 

LucaMs

Expert
Licensed User
Longtime User
Non lo so ma non dare la colpa alle B4XPages, lo avresti avuto anche in un'Activity, molto probabilmente ?

Fai creare la dichiarazione al Designer, facendo attenzione che in quel momento sia attivo il modulo di classe (B4XPage) giusto, ovvero se nel Designer hai il layout che sarà usato da B4XMainPage, che questa sia aperta nell'editor e non un altro modulo.

Designer. Menu: Tools - Generate Members

1700577237011.png


Nota che ho spuntato B4XView, in modo che Label, Panel, Button, ... vengano dichiarati come B4XView e quindi il progetto sarà più compatibile anche con B4J e B4i.
Per lo stesso motivo dovresti aggiungere al layout delle B4XImageView anziché delle ImageView. Il problema delle prime è che, se non sono cambiate le cose recentemente, non hanno alcuni eventi, principalmente il Click. Se necessario, dovrai sovrapporre alla B4XImageView un Panel trasparente ed usare l'evento Click (o Touch) di quest'ultimo. Io aggiunsi questi due eventi ma non ricordo se poi pubblicai la mia versione di B4XImageView (ma cercherò ed aggiornerò questo post).

P.S. lmB4XImageView
 

Fulvio75

Well-Known Member
Licensed User
Non lo so ma non dare la colpa alle B4XPages, lo avresti avuto anche in un'Activity, molto probabilmente ?

Fai creare la dichiarazione al Designer, facendo attenzione che in quel momento sia attivo il modulo di classe (B4XPage) giusto, ovvero se nel Designer hai il layout che sarà usato da B4XMainPage, che questa sia aperta nell'editor e non un altro modulo.

Designer. Menu: Tools - Generate Members

View attachment 147966

Nota che ho spuntato B4XView, in modo che Label, Panel, Button, ... vengano dichiarati come B4XView e quindi il progetto sarà più compatibile anche con B4J e B4i.
Per lo stesso motivo dovresti aggiungere al layout delle B4XImageView anziché delle ImageView. Il problema delle prime è che, se non sono cambiate le cose recentemente, non hanno alcuni eventi, principalmente il Click. Se necessario, dovrai sovrapporre alla B4XImageView un Panel trasparente ed usare l'evento Click (o Touch) di quest'ultimo. Io aggiunsi questi due eventi ma non ricordo se poi pubblicai la mia versione di B4XImageView (ma cercherò ed aggiornerò questo post).

P.S. lmB4XImageView

funziona avevo messo nel percorso delle ImageView il file da visualizzare e cosi non andava, ora lo faccio da codice e va anche se le ho dichiarate ImageView.
 

Fulvio75

Well-Known Member
Licensed User
Altra cosa...

tutti gli eventi tipo Activity_KeyPress ecc.ecc. non funzionano in B4XMainPage, ma in Main si perchè?

questa cosa:

B4X:
Sub Activity_KeyPress (KeyCode As Int) As Boolean
    
    Select KeyCode
        
        Case KeyCodes.KEYCODE_BACK
            
            If ELM327.Connecting = True Then
                
                CallSub2(B4XPages.MainPage,"Waiting_Show","Annullamento connessione...")

                'annullo la connessione
                ELM327.CancelConnecting = True
                
            End If
            
    End Select
    
    Return True
    
    'Return B4XPages.Delegate.Activity_KeyPress(KeyCode)
    
End Sub

va solo in Main se invece la voglio in B4XMainPage non funziona e non sente Activity_KeyPress
poi ho commentato:
Return B4XPages.Delegate.Activity_KeyPress(KeyCode)
altrimenti va in pause
 

LucaMs

Expert
Licensed User
Longtime User
tutti gli eventi tipo Activity_KeyPress ecc.ecc. non funzionano in B4XMainPage, ma in Main si perchè?
Perché devi "dimenticare" Activity e quindi tutti i suoi eventi.

Come per qualsiasi altro oggetto, l'Editor ti aiuta a generare la Sub-evento, elencandoti quelli disponibili:
1.gif


Per quanto riguarda KeyPress:
https://www.b4x.com/android/forum/t...o-handle-activity_keypress.118990/post-744274
https://www.b4x.com/android/forum/threads/b4xpages-intercepting-keypress.139118/post-880705
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Il punto è che non esiste un B4XPage_KeyPress.
Erel ha fatto in modo che la pressione del tasto Back faccia scattare l'evento B4XPage_CloseRequest, ma tutti gli altri tasti premuti?
Ecco perché poco fa ho scritto quel "Wish" (vedi mio post precedente).
 
Top