Android Question Exception while converting List to ByteArray

artsoft

Active Member
Licensed User
Longtime User
Hi all!

I have a question:

This thread https://www.b4x.com/android/forum/threads/how-to-convert-list-to-byte-array.67303/ explains on how to convert a normal list into a byte array.

@Erel provided this simple method for that:
B4X:
Sub ListToBytes(list As List) As Byte()
   Dim b(list.Size) As Byte
   For i = 0 To list.Size - 1
     b(i) = list.Get(i)
   Next
   Return b
End Sub

But, what happens if each entry in the list object has more than 1 byte.

Example:
My list contains 4 entries.
Each entry has such a content: "Hello World".
The list.size is 4 and the target byte array has only a size of 4 bytes.

This makes sense, because - while using this method - I get always this error:

B4X:
Error occurred on line: 613 (Tools)
java.lang.NumberFormatException: For input string: "[B@15041a8"
    at jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
    at jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:543)
    at anywheresoftware.b4a.debug.RDebugUtils.numberCast(RDebugUtils.java:63)
    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:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:265)
    at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
    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.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
    at anywheresoftware.b4a.keywords.Common$14.run(Common.java:1748)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:210)
    at android.os.Looper.loop(Looper.java:299)
    at android.app.ActivityThread.main(ActivityThread.java:8168)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1037)

And line 613 is this one:
B4X:
b(i) = list.Get(i)

Is there something missing?
Or should I cast something to another type?

Perhaps somebody can help here.

Additional information:
My list object contains data from Audiostreamer (see example for recording audio data). In this example a normal list is used as "audiobuffer".

Regards and thanks in advance
ARTsoft
 
Last edited:
While using this method

The list in that thread ONLY contains ONE Character in each entry. For THIS List you can use that Method.
how to convert a normal list into a byte array
Only if the List only contains single Bytes.

I can´t see what you are doing there. Upload a small project showing your issue. This can help much in understanding what you are doing.
 
Upvote 0
The list in that thread ONLY contains ONE Character in each entry. For THIS List you can use that Method.

Only if the List only contains single Bytes.

I can´t see what you are doing there. Upload a small project showing your issue. This can help much in understanding what you are doing.

Thanks DonManfred :-)

Yes, this was also in my opinion.

What I need is a method which extract each (String) entry in the list in order to interate each byte in this string - in order to save each byte in the target byte array.

Is there already such a method in B4A which does the same?
Or should I create my own method?

Regards
 
Upvote 0
It is a bit unclear what exactly you are trying to archieve.

What I need is a method which extract each (String) entry
which STRING?

Additional information:
My list object contains data from Audiostreamer

Data from Audiostreamer are binary-data and not Strings.
To collect the bytes you should use
B4X:
list.AddAll(bytesfromaudiostreamer) ' Where list is your Listobject...
 
Upvote 0
It is a bit unclear what exactly you are trying to archieve.


which STRING?



Data from Audiostreamer are binary-data and not Strings.
To collect the bytes you should use
B4X:
list.AddAll(bytesfromaudiostreamer) ' Where list is your Listobject...

Absolutely right, DonManfred! Bad wording :-( using the word String - I mean the bytes.
My mistake!

The audio streaming data (after a sound recording) is already (!) saved in a list object (see below 'audioBuffer').
So there is no need to use "AddAll" method.

There is an AudioStream example in this forum and I used this in order to see on how the developer recorded some audio data:

B4X:
Private audioBuffer As List

Private Sub streamer_RecordBuffer (Buffer() As Byte)
  
    audioBuffer.Add(Buffer)   ' audioBuffer is a list object!
  
End Sub

So the following action is now to convert all data (saved in audioBuffer list) into a simple byte array.

Thanks and regards
 
Last edited:
Upvote 0
This is the method for converting a byte array to a normal list (as you said using the AddAll method):

B4X:
Public Sub ByteArrayToList (b() As Byte) As List

    Dim retList As List : retList.Initialize

    retList.AddAll(b) 
  
    Return retList

End Sub

And for the other direction I need also a method:

And based on the fact, that the "streamer_RecordBuffer" callback method (see above) always adds a new byte array to the list, there is a need to have the other method to convert such a list (filled with byte arrays!) back into a onyl 1 (big) byte array.

I tried this - but I think this is wrong:

B4X:
Public Sub ListToBytes(list As List) As Byte()
  
    Dim count As Int = 0
  
    For Each b() As Byte In list
        count = count + b.Length
    Next
  
    Dim retB(count) As Byte
  
    Dim seek As Long = 0
    Dim b() As Byte
  
    For i = 0 To list.Size - 1
        b = list.Get(i)
        If (b.Length > 0) Then
            For j = 0 To b.Length-1
                retB(seek + j) = b(j)
            Next
            seek = seek + b.Length
        End If
    Next

    Return retB
  
End Sub

Firstly I detect the complete lengths of all byte arrays in the list in order to summarize these.

With this complete length I create the byte array "retB".

Then I copy (byte by byte) each byte to the target byte arry. But I guess there is a better method ... a quicker method ... to do this!

Regards
 
Upvote 0
B4X:
    Dim newbytes(10) As Byte ' Image this is your bytearray from the audiostreamer.
   
    Dim l As List ' Image this is your capturebuffer-List
    l.Initialize
    l.AddAll(newbytes)
    Log(l.Size) ' Logs 10

Creating a new List is not mandatory.

Dear DonManfred!

This code is ok - but I need the "other" way ... the "other" direction -->

Public Sub ListToBytes(list As List) As Byte()
...
End Sub

I have a list with entries, each entry is a byte array:

B4X:
List has 5 entries:

|-------1------|-------2------|-------3------|-------4------|-------5-----|
|b(0)|b(1)|b(2)|b(0)|b(1)|b(2)|b(0)|b(1)|b(2)|b(0)|b(1)|b(2)|b(0)|b(1)|b(2)
|--------------|--------------|--------------|--------------|-------------|

Each entry has 3 bytes.

The goal is to have a byte array with 15 bytes.

Unfortunately this code doesn't work properly:

B4X:
Public Sub ListToBytes(list As List) As Byte()
    
    Dim o As OutputStream
    
    o.InitializeToBytesArray(0)

    Dim b() As Byte
    
    For i = 0 To list.Size - 1
        b = list.Get(i)
        o.WriteBytes(b, 0, b.Length)
    Next
    
    Dim retB() As Byte = o.ToBytesArray
    
    o.Close

    Return retB
    
End Sub

Thanks a lot DonManfred for your help!

Regards
 
Upvote 0
Back
Top