Italian Evento non intercettato...

stefanoxjx

Active Member
Licensed User
Longtime User
Ciao a tutti, dopo tanto mi sto rimettendo a fare qualcosa con B4A, nel frattempo mi sono dimenticato quel poco che avevo imparato :(

Sto giocando un po' con l'sms interceptor e con la fotocamera, ma c'è qualcosa che mi sfugge.
La classe Camera dovrebbe generare un evento Camera_Ready che però mi sembra non venga proprio intercettato.
Il codice che ho scritto, intercetta un sms in arrivo e apre una activity che dovrebbe in automatico scattare una foto, ma non lo fa :(
Questo è il codice:

Main
B4X:
#Region  Project Attributes 
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName: 
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes 
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
End Sub

Sub Globals
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("MainGabbia")
    StartService(Starter)
    Activity.Finish
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Starter (Servizio)
B4X:
#Region  Service Attributes 
    #StartAtBoot: False
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals
    Dim si As SmsInterceptor
    Dim tts1 As TTS
'    Dim pc As PhoneCalls
End Sub

Sub Service_Create
    si.Initialize2("si", 999)
    tts1.Initialize("tts1")
End Sub

Sub Service_Start (StartingIntent As Intent)
    StartServiceAt("", DateTime.Now + 0.1 * DateTime.TicksPerMinute, False)
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


Sub si_MessageReceived (From As String, Body As String) As Boolean
    If Body="parla" Then
        tts1.Speak("Messaggio ricevuto da: " & From & Body, True)
    End If
    StartActivity(TakePicture)

    Return True 'con questa istruzione si ritorna direttamente al chiamante senza inoltrare il messaggio al sistema
End Sub

TakePicture
B4X:
#Region  Activity Attributes 
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
   
End Sub

Sub Globals
    Dim camera1 As Camera
    Dim Panel1 As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("PhotoLayout")
    camera1.Initialize(Panel1, "Camera1")
'     camera1.StartPreview'
    'camera1.AutoFocus
    'camera1.TakePicture
    'Activity.Finish
End Sub

Sub Activity_Resume
    camera1.Initialize(Panel1, "Camera1")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    camera1.Release
End Sub

Sub Camera1_Ready (Success As Boolean)
    'camera1.Initialize(Panel1, "Camera1")
    camera1.StartPreview
    camera1.AutoFocus
    camera1.TakePicture
   
    If Success Then
        camera1.StartPreview
    Else
        ToastMessageShow("Cannot open camera.", True)
    End If
End Sub

Sub Camera1_PictureTaken (Data() As Byte)
'    camera1.StartPreview
    Dim out As OutputStream
    out = File.OpenOutput(File.DirRootExternal, "1.jpg", False)
    out.WriteBytes(Data, 0, Data.Length)
    out.Close
    ToastMessageShow("Image saved: " & File.Combine(File.DirRootExternal, "1.jpg"), True)
'    btnTakePicture.Enabled = True
End Sub

Di conseguenza, nemmeno Camera1_PictureTaken viene intercettato.

Questi invece sono gli errori che vengono riportati:
upload_2016-7-1_11-43-11.png


Dove sto sbagliando?

Grazie.

Stefano
 

udg

Expert
Licensed User
Longtime User
Ciao,

lo stesso Erel consiglia di utilizzare CameraEx. Ad ogni modo, ho provato a ripulire il codice TakePicture pur non avendo modo di provarlo. Vedi se così ti riporta lo stesso errore o se in qualche modo fila liscio.

B4X:
#Region Activity Attributes 
#FullScreen: False
#IncludeTitle: True#
End Region

Sub Process_Globals
End Sub

Sub Globals
Dim camera1 AsCamera 
Dim Panel1 AsPanel         'presumo derivi da PhotoLayout
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("PhotoLayout")
'camera1.Initialize(Panel1, "Camera1") 'se inizializzi in Resume, questo va disabilitato altrimenti inizializzi 2 volte di seguito
End Sub

Sub Activity_Resume
camera1.Initialize(Panel1, "Camera1")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
camera1.Release
End Sub

Sub Camera1_Ready (Success As Boolean)
If Success Then
   camera1.StartPreview
   camera1.AutoFocus
   camera1.TakePicture
Else
  ToastMessageShow("Cannot open camera.", True)
End If 
End Sub

Sub Camera1_PictureTaken (Data() As Byte)
Dim out AsOutputStream
out = File.OpenOutput(File.DirRootExternal, "1.jpg", False)
out.WriteBytes(Data, 0, Data.Length)
out.Close
ToastMessageShow("Image saved: " & File.Combine(File.DirRootExternal, "1.jpg"), True)
' btnTakePicture.Enabled = True
End Sub

Immagino che una volta scattata una foto bisogna terminare TakePicture e riprendere il tutto dall'inizio. Se così non fosse, credo che Startpreview vada eseguito di nuovo al termine di PictureTaken perché mi sembra di ricordare che lo scatto di una foto erminava anche la preview, ma non è detto.

udg
 

stefanoxjx

Active Member
Licensed User
Longtime User
@udg: il tuo codice funziona. Alla fine era solo la doppia inizializzazione che dava problemi?
Ora vorrei fare in modo che una volta che l'activity TakePicture abbia finito di fare il suo compito, termini.
Se dipendesse da me inserirei un Activity.Finish in Camera1_ready subito dopo camera1.TakePicture, ma ho dei dubbi che Camera1_PictureTaken faccia in tempo a fare il suo lavoro prima che l'activity venga uccisa.
Mi conviene mettere Activity.Finish alla fine di Camera1_PictureTaken?
C'è modo di settare da software i parametri della fotocamera (esempio il flash in automatico)?
Sulla documentazione di "Camera" non c'è scritto nulla :(
Grazie.

Stefano
 

udg

Expert
Licensed User
Longtime User
Ciao Stefano.

Decisamente l' activity.finish va in Camera1_PictureTaken.

A dirla tutta, siccome anche autofocus credo abbia un suo evento (FocusDone), la catena dovrebbe essere:

ready -> autofocus -> takePicture -> finish

In pratica ogni sub avvia una funzione asincrona che ha una sua sub per avvisare che abbia terminato (e magari anche un codice di completamento, guarda la doc) ed è quest'ultima a lanciare la prox funzione asincrona.
Quindi Ready esegue prima StartPreview (che non ha eventi) e poi AutoFocus
FocusDone lancerebbe TakePicture
PictureTaken eseguirebbe activit.finish

A quel punto il codice di uscita esegue il Pause e quindi opera il camera.release.

Camera è molto limitato (e datato). Con CameraEx hai molte possibilità in più.
 
Last edited:
Top