Android Question problem WHIT CharAt

r.babazadeh

Member
Licensed User
Longtime User
The problem STRING.CharAt (i) with more than 128 characters
For all values of greater than 128 returns -3
 

Roycefer

Well-Known Member
Licensed User
Longtime User
String.CharAt() returns a char type, not a byte type. In Java, the char type is 16 bits wide and can range from 0 to ~65k. It is used to store a 16-bit Unicode character reference, so it should be able to easily accommodate your ASCII codes. Can you show some sample code and a String that produces this behavior?
 
Upvote 0

RandomCoder

Well-Known Member
Licensed User
Longtime User
String.CharAt() returns a char type, not a byte type. In Java, the char type is 16 bits wide and can range from 0 to ~65k. It is used to store a 16-bit Unicode character reference, so it should be able to easily accommodate your ASCII codes. Can you show some sample code and a String that produces this behavior?
My mistake, CharAt does indeed return a Char data type and not a Byte as I first assumed. :oops:
 
Upvote 0

sonicmayne

Member
Licensed User
Longtime User
I wrote the following code which works as expected and outputs each character in a 256 character string.

B4X:
    Dim SB As StringBuilder
    SB.Initialize
    For i = 0 To 255
        SB.Append(Chr(Rnd(65,99)))
    Next
    Dim s As String = SB.ToString
    Log(s)
    For i = 0 To s.Length - 1
        Log(i & ": " & s.CharAt(i))
    Next

Can you show us the code you are using so we can try and reproduce it?
 
Upvote 0

r.babazadeh

Member
Licensed User
Longtime User
Code:
Dim c As Char
dim bi as byte
Dim c As Char
dim s as string
dim voltage as int

Sub AStreams_NewData (Buffer() As Byte) As String

s = BytesToString( Buffer , 0, Buffer.Length, "ASCII")

c=s.CharAt(i)
bi=Asc(c)
voltage=bi





Thank you for your attention
Is it the amount of code is enough?
My problem was, say ASCII character in the variable c is larger than 128 or the 8-bit ASCII one
 
Last edited:
Upvote 0

RandomCoder

Well-Known Member
Licensed User
Longtime User
I'm not at my PC at the moment to enable me to show a working example but as you already have an array of bytes why convert to a string and then back to bytes? Just work with the bytes directly.
 
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
Without knowing where your AsyncStream is getting its data, I can only make some guesses. It might be that your data source only sends data in frames of 128 bytes. If you know your data is going to be interpreted as text, you might be better off using the AsyncStreamsText class. It collects frames of raw bytes until it reads a newline character and then raises the _NewText(Text as String) event. This allows you not to bother with collecting byte buffers and turning them into text and just deal with the text directly, as a String.

Also, are you sure ASCII is a supported character set? I seem to recall ASCII was deprecated a while ago and it is now considered a subset of UTF-8.

Furthermore, I'm not sure what the mapping is between UTF-8/ASCII and UTF-16 is but I know Java stores Strings internally as UTF-16 (that's why char is 16-bit). Even though you specified that BytesToString use ASCII, the resulting String s will still be represented in UTF-16. So when you call Asc(c), this value (which is of int type) could easily overflow the limits of the byte type. Like Random said, if you just need the bytes, you should just work with them directly. If you need Strings, you should use the AsyncStreamsText class.
 
Upvote 0

r.babazadeh

Member
Licensed User
Longtime User
I Send below data Whit micro controller via Bluetooth

Tx_tbl(01) = "L"
Tx_tbl(02) = Ip
Tx_tbl(03) = Nip
Tx_tbl(04) = L_speed
Tx_tbl(05) = H_speed
Tx_tbl(06) = light



For example, information of Several switch on the variable (light), which switch is one bit of this variable.
This variable is sent as a character.
The receiver I have bits separated
 
Upvote 0

r.babazadeh

Member
Licensed User
Longtime User
Without knowing where your AsyncStream is getting its data, I can only make some guesses. It might be that your data source only sends data in frames of 128 bytes. If you know your data is going to be interpreted as text, you might be better off using the AsyncStreamsText class. It collects frames of raw bytes until it reads a newline character and then raises the _NewText(Text as String) event. This allows you not to bother with collecting byte buffers and turning them into text and just deal with the text directly, as a String.

Also, are you sure ASCII is a supported character set? I seem to recall ASCII was deprecated a while ago and it is now considered a subset of UTF-8.

Furthermore, I'm not sure what the mapping is between UTF-8/ASCII and UTF-16 is but I know Java stores Strings internally as UTF-16 (that's why char is 16-bit). Even though you specified that BytesToString use ASCII, the resulting String s will still be represented in UTF-16. So when you call Asc(c), this value (which is of int type) could easily overflow the limits of the byte type. Like Random said, if you just need the bytes, you should just work with them directly. If you need Strings, you should use the AsyncStreamsText class.


It is equal to the output ascii and utf8.
I thought are different

I think the command Asc (c) is overflow and so characters with ASCII code higher than 127 is Fixed and returns -3
 
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
What microcontroller? If it's an Arduino or something like it (using an 8-bit instruction set), it's most likely using UTF-8/ASCII and its "char" is a C/C++ char which is usually only 8 bits wide and unsigned (which means it can overflow a Java byte type which is signed). Manually converting it into a Java-compatible UTF-16 will be a pain. And Erel has already done that work for you in AsyncStreamsText. I recommend using that and you'll be able to see the Java representation of the chars sent by the microcontroller.
 
Upvote 0
Top