German eingene Log-Datei führen

peternmb

Well-Known Member
Licensed User
Longtime User
Hallo,

ich möchte eine eigene Log-Datei führen, um mein Programm betreffende Aktionen einzutragen. Die Datei sollte sich dann anzuzeigen oder auch leeren lassen. Das könnte z.B. eine einfache txt-Datei sein, in die zeilenweise alles eingetragen wird.

Gibt es da bereits irgendetwas fertiges oder muss ich das neu machen?

Wenn es nichts fertiges gibt, was wäre dann der einfachste Weg das zu realisieren?
 

klaus

Expert
Licensed User
Longtime User
So viel Ich weiss gibt es keine fertige Lösung, Du musst es also selbst machen.
Ich würde es wie folgend machen:
- Wenn das Programm gestartet wird, in Activity_Resume die Datei entweder erstellen oder laden mit einem TextWriter Objekt.
- Jedesmal wenn Du einen Eintrag schreiben willst mit WriteLine("Text") eine Zeile der Datei zufügen.
- In Activity_Pause die Datei schliessen mit TextWriter.Close

Zum lesen und löschen eine spezielle Activity dafür erstellen.

Beste Grüsse.
 

peternmb

Well-Known Member
Licensed User
Longtime User
vielen Dank, das mit dem Schreiben klappt prima so.

Ich würde die Ausgabe gerne in einem CustomDialog anzeigen.
Kann ich das ähnlich einem WebView relativ einfach erzeugen?

Sub show_log
'Log-Datei anzeigen und evl. löschen
Dim cd As CustomDialog
Dim pnl As Panel
pnl.Initialize("pnl")
Dim bgnd As ColorDrawable
bgnd.Initialize(Colors.Black, 5dip)
pnl.Background = bgnd
'
'
Dim wv As WebView
wv.Initialize("")
pnl.AddView(wv,0,0,650,400)
wv.LoadUrl("file:///android_asset/hilfe.html")
cd.AddView(pnl, 0%x, 0%y, 650,400)
'
'
ret = cd.Show("interne Log-Datei", "Fenster schliessen","Log-Datei leeren","", Bild4)
If ret = DialogResponse.POSITIVE Then
Return
Else If ret = DialogResponse.CANCEL Then
Writer.Close
Writer.Initialize(File.OpenOutput (ListDir, "LF.log", False))
AddLog("Log-Datei geleert")
show_log
End If
End Sub
 
Last edited:

klaus

Expert
Licensed User
Longtime User
Ich habe so etwas noch nie probiert auch keinen CustomDialog.
Solche Sachen mache Ich selbst, wahrscheinlich eine 'alte' Angewohnheit.
Ich Wurde es mit einer ScrollView und einem Label grösser als der Bildschirm und Buttons zur Auswahl in einer eigenen Activity.
Eine Mischung von LongTextSimple und HelpDisplay.
Aber das ist nur mein Gefühl.

Beste Grüsse.
 

peternmb

Well-Known Member
Licensed User
Longtime User
Das klappt prima und ganz einfach mit deinem Beispiel LongTextSimple in einem CustomDialog :sign0060:

B4X:
Sub show_log  
  'Log-Datei anzeigen und evl. löschen 
  Dim cd As CustomDialog 
  Dim pnl As Panel
  pnl.Initialize("pnl")
  Dim bgnd As ColorDrawable
  bgnd.Initialize(Colors.RGB(250, 250, 210), 5dip)
  pnl.Background = bgnd
  '   
  '
  scvText.Initialize(100)                                ' initialize the Scrollview
  'Activity.AddView(scvText, 0, 0, 100%x, 100%y)         ' add the Scrollview on the Activity
  pnl.AddView(scvText, 0, 0, 650, 380)                   ' add the Scrollview on the Activity
  '
  lblText.Initialize("")                                 ' initialize the Label for the text, without an EventName
  scvText.Panel.AddView(lblText, 0, 0 ,100%x, 100%y)     ' add the Label on the ScrollView internal Panel
  lblText.Color = Colors.RGB(250, 250, 210)              ' set the Label background color
  lblText.TextColor = Colors.Black                       ' set the Label text color
  '  
  LoadText                                               ' load the text
  SetText                                                ' set the text
  '   
  cd.AddView(pnl, 0%x, 0%y, 650,400) 
  '
  ret = cd.Show("interne Log-Datei", "Fenster schliessen","Log-Datei leeren","", Bild4)
  If ret = DialogResponse.POSITIVE Then
    helfen_Click
  Else If ret = DialogResponse.CANCEL Then 
    Writer.Close
    Writer.Initialize(File.OpenOutput (ListDir, "LF.log", False))
    AddLog("Log-Datei wurde vom Benutzer geleert - OK")
    show_log   
  End If
End Sub


Sub LoadText
  Writer.Close
  '   
  txt = File.GetText(ListDir, "LF.log")    ' load the text file into the string
  ' 
  Writer.Initialize(File.OpenOutput (ListDir, "LF.log", True))
End Sub

Sub SetText
  Dim ht As Float
  '      
  lblText.Text = txt                     ' set the text string to the Label text property
  ht = StrUtil.MeasureMultilineTextHeight(lblText, txt)    ' measure Label height
  scvText.Panel.Height = ht              ' set the ScrollView internal Panel height to the measured height
  lblText.Height = ht                    ' set the Label height to the measured height
  '
  scvText.ScrollPosition = 0             ' set the scroll position to the top of the text
  DoEvents                               ' needed to execute the previous line
End Sub

Sub AddLog(was As String)
  Dim now As Long
  now = DateTime.now
  Writer.WriteLine( DateTime.Date(now)&" "&DateTime.Time(now)&" - " & was)
End Sub

@Klaus - gibt es einen Grund warum du keine CustomDialoge verwendest?
Ich finde die einfach genial praktisch für einfache Ausgaben und man spart sich z.B. die Buttons und die entsprechenden Subroutinen :cool:
 

klaus

Expert
Licensed User
Longtime User
B4X:
@Klaus - gibt es einen Grund warum du keine CustomDialoge verwendest?
Nein. Ich habe die vielleicht einmal getestet aber nie benutzt wie schon mal gesagt alte Angewohnheit das Meiste selbst zu machen.

Ich erlaube mir ein Paar Kommentare zu deinem Code:
- Für leere Zeilen ist das Apostroph in B4A nicht nötig
- Es ist besser mit dip Werten zu arbeiten als mit absoluten Pixels.
Beispiel:
anstatt cd.AddView(pnl, 0%x, 0%y, 650,400)
cd.AddView(pnl, 0, 0, 650dip, 400dip)
Das hat den Vorteil dass dein Code auch auf Geräten mit ungefähr gleichen Bildschirmassen mit einer Density ungleich 1 auch noch gut aussieht.
0%x ist nicht nötig, null bleibt null.
Ansonsten gefällt mir dein Programmierstil.

Beste Grüsse.
 

peternmb

Well-Known Member
Licensed User
Longtime User
Es ist besser mit dip Werten zu arbeiten als mit absoluten Pixels.
vielen Dank für den Hinweis

Für leere Zeilen ist das Apostroph in B4A nicht nötig
ich weiss, das ist mir aber so lieber damit ich besser sehe was zusammengehört

Danke für die Hinweise und das Lob, klingt schon besser als am Anfang, wo du meinen Code glaube ich als "komisch" eingestuft hast :sign0089:

Womit ich jetzt noch Probleme habe ist, das Log als PDF zu exportieren.
Es wird alles als eine einzige lange Zeile im PDF angezeigt. Ich müsste den Text zeilenweise "zerhacken".
B4X:
Sub machPDF  
  PDFWriter1.Initialize("PDFWriter1",PaperSize.A4_WIDTH, PaperSize.A4_HEIGHT)
  '
  Writer.Close
  '
  txt = File.GetText(File.DirInternal, "LF.log")    ' load the text file into the string
  PDFWriter1.addText(10,800,11,txt)
  *
  Writer.Initialize(File.OpenOutput (File.DirInternal, "LF.log", True))
  '
  PDFWriter1.ConverseDocument
End Sub

Sub PDFWriter1_ConversionDone (Content As String)
  PDFContent = Content
  ProgressDialogHide
  ToastMessageShow("Conversion has been done.",False)
  '
  PDFWriter1.outputToFile(ListDir,"Log.pdf",PDFContent,"ISO-8859-1")
  ToastMessageShow("PDF Saved.",False)
  '
End Sub
 

peternmb

Well-Known Member
Licensed User
Longtime User
-In B4A (Android / Java) entspricht die Konstate CRLF Chr(10).
In Windows braucht man Chr(10)&Chr(13).
Versuche am Ende jeder Zeile Chr(13) anzufügen.

Beste Grüsse.

aber was hat das mit Windows zu tun? Ich erstelle das PDF doch mit der B4A-PDFWriter-Funktion.

Ja, es sieht so aus als würden vom PDF-Writer die Zeilenvorschübe nicht erkannt.
Da dürfte das ISO-8859-1 das Problem sein. Hat vielleicht jemand eine Ahnung auf was ich das ändern müsste um eine UTF8-kodierte Datei korrekt einzulesen.
 

peternmb

Well-Known Member
Licensed User
Longtime User
Vielen Dank, ich habe es jetzt anders gelöst.

Ich lasse nicht mehr meine ganze Log-Datei auf einmal schreiben, sondern lese die zeilenweise in ein Array ein, das ich dann auch zeilenweise schreiben lasse. Das hat u.A. den Vorteil, dass ich die Zeilenabstände und den Seitenwechsel im PDFDokument einfach selber festlegen kann.

Hier der (recht simple) Code falls es jemand gebrauchen kann :)
B4X:
Sub machPDF  
  PDFWriter1.Initialize("PDFWriter1",PaperSize.A4_WIDTH, PaperSize.A4_HEIGHT)
  Writer.Close
  '
  Dim PDFVar As List                        
  Dim zeile As Int : zeile=820
  PDFVar = File.readlist(File.DirInternal,"LF.log")
  '
  For i = 0 To PDFVar.Size -1
    PDFWriter1.addText(10,zeile,10,PDFVar.Get(i))
    zeile=zeile-11
    If zeile<20 Then
      zeile=820      
      PDFWriter1.newPage
    End If
  Next   
  '
  Writer.Initialize(File.OpenOutput (File.DirInternal, "LF.log", True))
  PDFWriter1.ConverseDocument
End Sub


Sub PDFWriter1_ConversionDone (Content As String)
  PDFContent = Content
  PDFWriter1.outputToFile(ListDir,"Log.pdf",PDFContent,"ISO-8859-1")
  ' 
  ToastMessageShow("PDF-Dokument wurde erzeugt und gespeichert.",False)
  '
End Sub
 
Top