Android Question Convert String Expression To Label

RockSmoke

Member
Good day to everyone. In my project on B4A, I convert the data I receive over BLE to UTF-8 units. Then I want to give it to the screen via the label, but I am getting such an error. How do i convert to label text
Thanks For Your Answer.

ERROR MESSAGE : (TextView) android.widget.TextView{82e135b V.ED..... ......ID 0,1677-1074,1840 #f aid=1073741836}

B4A:
Dim lbl2 As B4XView = XUIViewsUtils.CreateLabel
Private Label3 As Label

    lbl2.Text = BytesToString(Data, 0, Data.Length, "UTF8")
    Label3.Text=lbl2.Text
 

emexes

Expert
Licensed User
convert the data I receive over BLE to UTF-8

I'm going to guess: Data is incomplete, with Unicode characters >= 128 being split across BLE packets and thus misinterpreted.

Perhaps try logging the raw incoming data at the point that it is received, eg:

B4X:
Sub BLE_Data_Received(Data() As Byte)

    Dim sb As StringBuilder
    sb.Initialize
   
    sb.Append("Received " & Data.Length & "bytes via BLE = (")
    For I = 0 To Data.Length - 1
        If I <> 0 Then
            sb.Append(", ")
        End If
        sb.Append(Bit.And(Data(I), 0xFF))
    Next I
    sb.Append(")")
   
    Log(sb.ToString)
   
End Sub

and post the Log right-click-Copy-all-to-clipboard result. 🍻
 
Last edited:
Upvote 0

RockSmoke

Member
I'm going to guess: Data is incomplete, with Unicode characters >= 128 being split across BLE packets and thus misinterpreted.

Perhaps try logging the raw incoming data at the point that it is received, eg:

B4X:
Sub BLE_Data_Received(Data() As Byte)

    Dim sb As StringBuilder
    sb.Initialize
  
    sb.Append("Received " & Data.Length & "bytes via BLE = (")
    For I = 0 To Data.Length - 1
        If I <> 0 Then
            sb.Append(", ")
        End If
        sb.Append(Bit.And(Data(I), 0xFF))
    Next I
    sb.Append(")")
  
    Log(sb.ToString)
  
End Sub

and post the Log right-click-Copy-all-to-clipboard result. 🍻
thanks for your answer. how do i convert these ascii codes to char
 
Upvote 0

emexes

Expert
Licensed User
thanks for your answer. how do i convert these ascii codes to char

Chr(65) returns a Char (or a single character String) of ASCII character number 65 (uppercase A)
Asc("A") returns ASCII character number of "A" ie 65

B4X:
Dim C as Char = Chr(65)    'ASCII character 65 is "A"
Log(C)

Dim S as String = Chr(65) & Chr(66) & Chr(67)    'ASCII characters 65, 66, 67 are "ABC"
Log(S)

Dim Alphabet As String = ""
For L = 1 To 26
    Alphabet = Alphabet & Chr(64 + L)    'ASCII characters 64 + 1 to 64 + 26 are "A" to "Z"
Next
Log(Alphabet)

Dim AsciiA As Int = ASC("A")
Dim AsciiZ As Int = ASC("Z")
For A = AsciiA To AsciiZ
    Log("ASCII character " & A & " is """ & Chr(A) & """")
Next

Do a Google search for ASCII table, choose the one you like best.

1665035324946.png
 
Upvote 0

emexes

Expert
Licensed User
thanks for your answer. how do i convert these ascii codes to char

Or if you mean: how do you convert a Byte array to a string of characters having the same values as the bytes, then:

B4X:
Dim A() As Byte = Array As Byte(65, 66, 67, 150, 160, 170)

Dim bc As ByteConverter
Dim S As String = bc.StringFromBytes(A, "ISO-8859-1")

will create String S with 6 characters, same as Chr(65) & Chr(66) & Chr(67) & Chr(150) & Chr(160) & Chr(170)

ISO-8859-1 is the 1:1 encoding that maps 8-bit bytes/characters 0-255 to Unicode characters 0-255

No, I don't know why they chose such an obvious and easy-to-remember name for the encoding. 🙃

Although you've got me thinking now: surely if no encoding is specified, then .StringFromBytes would default to the obvious 1:1 mapping... 🤔

edit: nope, need to specify the encoding, but on the bright side: (i) is case-insensitive, and (ii) the first hyphen is optional
 
Last edited:
Upvote 0

RockSmoke

Member
Chr(65) returns a Char (or a single character String) of ASCII character number 65 (uppercase A)
Asc("A") returns ASCII character number of "A" ie 65

B4X:
Dim C as Char = Chr(65)    'ASCII character 65 is "A"
Log(C)

Dim S as String = Chr(65) & Chr(66) & Chr(67)    'ASCII characters 65, 66, 67 are "ABC"
Log(S)

Dim Alphabet As String = ""
For L = 1 To 26
    Alphabet = Alphabet & Chr(64 + L)    'ASCII characters 64 + 1 to 64 + 26 are "A" to "Z"
Next
Log(Alphabet)

Dim AsciiA As Int = ASC("A")
Dim AsciiZ As Int = ASC("Z")
For A = AsciiA To AsciiZ
    Log("ASCII character " & A & " is """ & Chr(A) & """")
Next

Do a Google search for ASCII table, choose the one you like best.

View attachment 134468
Thank you very much for your explanations. very informative answer. I understand here.
Or if you mean: how do you convert a Byte array to a string of characters having the same values as the bytes, then:

B4X:
Dim A() As Byte = Array As Byte(65, 66, 67, 150, 160, 170)

Dim bc As ByteConverter
Dim S As String = bc.StringFromBytes(A, "ISO-8859-1")

will create String S with 6 characters, same as Chr(65) & Chr(66) & Chr(67) & Chr(150) & Chr(160) & Chr(170)

ISO-8859-1 is the 1:1 encoding that maps 8-bit bytes/characters 0-255 to Unicode characters 0-255

No, I don't know why they chose such an obvious and easy-to-remember name for the encoding. 🙃

Although you've got me thinking now: surely if no encoding is specified, then .StringFromBytes would default to the obvious 1:1 mapping... 🤔

edit: nope, need to specify the encoding, but on the bright side: (i) is case-insensitive, and (ii) the first hyphen is optional
Now I am converting the bytes I get from BLE, the point I am stuck on, but I cannot print it on the phone screen via the label. When I print string expression to label it disappears
 
Upvote 0

emexes

Expert
Licensed User
Hey, you're probably already on to this, but just in case:

ASCII is a 7-bit character set of 128 characters (2 ^ 7 = 2x2x2x2x2x2x2) numbered from 0 to 127 (or in binary, from 0000000 to 1111111).

Unicode is a much larger character set, containing thousands of characters and thus requiring more than 8 bits ie a single byte isn't enough.

But to keep backward compatibility, the first 128 Unicode characters 0 to127 match the ASCII characters 0 to 127. So, all ASCII is Unicode, but not all Unicode is ASCII.

UTF-8 is a way of encoding Unicode characters that aren't ASCII, into a group of (ie more than one) 8-bit bytes. Some Unicode characters need 2 UTF-8 bytes, some need 3, some need 4.

After working with characters and bytes and UTF-8 for years, all this becomes instinctive, and it's easy to forget that it's not immediately self-evident to others.
 
Upvote 0

RockSmoke

Member
By print, do you mean:

B4X:
Dim S As String = "important stuff"
Log(S)
Label1.Text = S
log(Label1.Text)
In this way, I can print text to the screen, but I cannot print the ''Dim S As String = bc.StringFromBytes(A, "ISO-8859-1")'' command to the screen. label becomes invisible
 
Upvote 0

emexes

Expert
Licensed User
Step one might be to look at the actual bytes coming in, eg:

B4X:
Dim PretendBleData() As Byte = Array As Byte(31, 41, 59, 26, 53, 58, 130, 140, 150)

Dim HumanReadable As StringBuilder
HumanReadable.Initialize

For I = 0 to PretendBleData.Length - 1
    If I <> 0 Then
        HumanReadable.Append(", ")
    End If
    HumanReadable.Append(Bit.And(PretendBleData(I), 0xFF))    'convert signed bytes -128..127 to unsigned 0..255
Next

Dim S As String = HumanReadable.ToString
Log(S)
Label1.Text = S
 
Upvote 0

emexes

Expert
Licensed User
this way i can see the bytes on screen but i can't see it as char

Any chance of posting a screen capture, or the byte values from the Log? (right-click, copy line to clipboard)

Also, based on those byte values, what "see it as char" string should be displayed?

Better yet, what happens if you add/change the highlighted lines of:

B4X:
Dim PretendBleData() As Byte = Array As Byte(31, 41, 59, 26, 53, 58, 130, 140, 150)

Dim HumanReadable As StringBuilder
HumanReadable.Initialize

For I = 0 to PretendBleData.Length - 1
    If I <> 0 Then
        HumanReadable.Append(", ")
    End If
    HumanReadable.Append(Bit.And(PretendBleData(I), 0xFF))    'convert signed bytes -128..127 to unsigned 0..255
Next

Dim S As String = HumanReadable.ToString
Log(S)
Dim bc As ByteConverter
Dim LS As String = bc.StringFromBytes(PretendBleData, "ISO-8859-1")    'or windows-1252 or UTF-8 ?
Log(LS)
Label1.Text = LS
 
Upvote 0

emexes

Expert
Licensed User
In this way, I can print text to the screen, but I cannot print the ''Dim S As String = bc.StringFromBytes(A, "ISO-8859-1")'' command to the screen. label becomes invisible

I just spotted A.

Are you sure it (A) isn't empty or full of nulls, control codes and/or spaces?

Perhaps add a Log(A.Length) before the above line, and a Log(S.Length & " : """ & S & """") after.
 
Upvote 0
Top