Send bytearray with bluetooth

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hey,

So I want to send a bytearray from my device to another device.
In the serial example, it uses textwriter/reader to write/read string.
I want to be able to send and receive the bytearray.
How do you write to the Serial.outputstream or another way?
B4X:
Dim btOut As OutputStream
      
   If connected Then
      btOut.WriteBytes(CurrentJPEG,0,CurrentJPEG.Length)

Thanks,
XverhelstX
 
Last edited:

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hey,

Thanks Erel.

1) In the log it says Sended, but there doesn't appear a msgbox on the screen:
B4X:
Sub Camera1_PreviewTaken (PictureFrame() As Byte)
   CurrentJPEG = PictureFrame
   strPreviewToString = b.HexFromBytes(PictureFrame)
   strPreviewToString = strPreviewToString.SubString2(0, 10)
   
   Msgbox(strPreviewToString, CurrentJPEG.Length)
   
End Sub
Sub Serial1_Connected (Success As Boolean)
   'Succesfully connected with a device.
   If Success Then
      AStreams.InitializePrefix(Serial1.InputStream, False, Serial1.OutputStream, "AStreams")
      ToastMessageShow("Connected successfully", False)
      TextReader1.Initialize(Serial1.InputStream)
      TextWriter1.Initialize(Serial1.OutputStream)
      
      tmrBluetooth.Enabled = True
      connected = True
   Else
      connected = False
      tmrBluetooth.Enabled = False
      Msgbox(LastException.Message, "Error connecting.")
   End If
End Sub

Sub mnuSend_Click
   
   If connected Then
      If AStreams.IsInitialized = False Then Return
         AStreams.Write(CurrentJPEG)
           Log("Sending: ")
    End If
      
   
End Sub

Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Msgbox(msg, "")
   
End Sub

Sub TMRBluetooth_Tick
   If connected Then
      
   End If
End Sub

2) When I do the following, my app stops unexpectedly:
B4X:
Sub Activity_KeyPress (KeyCode As Int) As Boolean
' R button: Ask to come live.
If Keycode = 103 Then
   If connected Then
      TextWriter1.WriteLine("Request: Live")
      TextWriter1.Flush
   
   Else
      Msgbox("You are not connected to a bluetooth device.","Connection")
   End If

End If

Sub TMRBluetooth_Tick
   If connected Then
      If TextReader1.Ready Then 'check if there is any data waiting to be read
         strReadLine = TextReader1.ReadLine
         Do While strReadLine <> Null
              Log(strReadLine)
              strReadLine = TextReader1.ReadLine
          Loop
         ToastMessageShow(strReadLine,True)
         
      End If
   End If
End Sub

3) As this is related to bluetooth, Do you know what the intent is to go to the bluetooth settings screen?
B4X:
Dim btIntent As Intent
btIntent.Initialize(btIntent.ACTION_MAIN, "")
btIntent..SetComponent("android.provider.Settings.ACTION_BLUETOOTH_SETTINGS")
StartActivity(btIntent)
The Sub Astreams_NewData should be called when new data arrives right?

XverhelstX
 
Last edited:
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
CurrentJPEG always gets a new value when the following code is done:

Sub Camera1_PreviewTaken (PictureFrame() As Byte)
CurrentJPEG = PictureFrame
strPreviewToString = b.HexFromBytes(PictureFrame)
strPreviewToString = strPreviewToString.SubString2(0, 10)

Msgbox(strPreviewToString, CurrentJPEG.Length)

End Sub

This executes the library created here, but doesn't give any errors. and msgbox is correctly displayed.

XverhelstX
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Ok, thanks.
The message is now displayed with the R button.
But CurrentJPEG is still not shown on the other device.

XverhelstX

EDIT: Ok, The problem was I had to wait :S now.
Although, A lot of strange sign appear now like ? in a square etc
Probably related to the encoding, but how I fix that.

XverhelstX
 
Last edited:
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Nevermind, Just see that i actually don't need that as I only need the buffer.

Is it actually possible to raise more than 1 asyncstream for example for your text and for your CurrentJPEG?
Or how would you see the difference between text coming in or the CurrentJPEG, as if you want to check the string,
CurrentJPEG should first changed to a string then and that takes something like 5 seconds. (not an option)

Also: As this is related to bluetooth, Do you know what the intent is to go to the bluetooth settings screen?
Code:
Dim btIntent As Intent
btIntent.Initialize(btIntent.ACTION_MAIN, "")
btIntent..SetComponent("android.provider.Settings.ACTION_BLUETOOTH_SETTINGS")
StartActivity(btIntent)
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You cannot share a stream between two AsyncStream objects. However you can send the image and then send the text. You can also use the first byte to mark the message type. You can see an example in B4A Bridge source code.

Why do you convert the image to string??? Why not send the raw bytes.

I do not know the bluetooth setting screen intent. If you don't find it I will help you to find it.
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
The image stream will continuosly stream to another device.
So if I add text to one, would it just go into a queue?

You can also use the first byte to mark the message type.

If you change the first byte of, will it change anything on the picture itself?
and on the B4A bridge, where exactly is the code that does it? and how does it work?

So it adds 1 unique identifier (byte) at the end of the stream (or at the beginning)?
B4X:
Sub AddCommandToBytes(Command As Byte, Buffer() As Byte, Length As Int) As Byte()
   Dim b(Length + 1) As Byte
   b(0) = Command
   BC.ArrayCopy(Buffer, 0, b, 1, Length)
   Return b
End Sub

and does it also remove it?

Why do you convert the image to string??? Why not send the raw bytes.
Yeah, I already figured it out. I didn't need to do that, Only to check if I actually did receive something.

xverhelstx

EDIT: I think I understand it.
So here:

B4X:
Sub AddCommandToBytes(Command As Byte, Buffer() As Byte, Length As Int) As Byte()
   Dim b(Length + 1) As Byte
   b(0) = Command
   BC.ArrayCopy(Buffer, 0, b, 1, Length)
   Return b
End Sub

It grabs the data from your buffer, and 1 to the length and as first number you give it the command byte.
Then you return a copy of it. and sends B then with AsyncStream. Nice ;D

So when this is done, You have to start reading from the first byte then right?
B4X:
Dim command As Byte
   command = Buffer(0)
   Select command
      Case TEXT_BYTE
         Dim msg As String
          msg = BytesToString(Buffer, 1 <-- first byte, Buffer.Length -1, "UTF8")
          Msgbox(msg, "")
      Case IMAGE_BYTE
         Dim msg As String
          msg = BytesToString(Buffer, 1, Buffer.Length -1, "UTF8")
          Msgbox(msg, "")
   End Select

OMG, These just works :eek: :D:D
Thanks A lot Erel :D
Although, Sometimes, I won't sent my message. Dunno why, but it happens only when I send my CurrentJPEG over??
Mostly, It sends the first time but then it doesn't anymore.
Like if I first send the CurrentJPEG, it works, but that both doesn't work anymore.

B4X:
Dim TEXT_BYTE, IMAGE_BYTE As Byte
   TEXT_BYTE = 1
   IMAGE_BYTE = 2
Sub mnuSend_Click
   
   If connected Then
      If AStreams.IsInitialized = False Then Return
         Astreams.Write(AddCommandToBytes(IMAGE_BYTE, CurrentJPEG, CurrentJPEG.Length))
           Log("Sending: Image ")
   Else
      Msgbox("You are not connected to your crew." & CRLF & "Select 'Start' to assign one.","Connection")
   
    End If
      
   
End Sub

' R button: Ask to come live.
If Keycode = 103 Then
   If connected Then
      If AStreams.IsInitialized = False Then Return
         strWriteText = "Permission: Record"
         Dim bfrWriteText() As Byte
           bfrWriteText = strWriteText.GetBytes("UTF8")
         
         AStreams.Write(AddCommandToBytes(TEXT_BYTE, bfrWriteText, bfrWriteText.Length))
           Log("Sending: Permission Record")
         
   Else
      Msgbox("You are not connected to your crew." & CRLF & "Select 'Start' to assign one.","Connection")
   End If

End If
 
Last edited:
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hey,

Me again.
Is it possible to use 2 Asyncstreams?
1 Asyncstream named Async2 and one named async2
note that now one is used in an activity for bluetooth and the other one is needed for socket connection in a service.

2) Still haven't found the intent bluetooth screen.
Otherwise I can enable the bluetooth programmatically as the following:

B4X:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    
if (!mBluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

but I get an error at startActivityForResult.

Thanks,
XverhelstX
 
Upvote 0

XverhelstX

Well-Known Member
Licensed User
Longtime User
Ok, but you can make a single bluetooth connection and a single socket connection in the same activity with different Async names? (like async1 for bluetooth and async2 for socket)?

XverhelstX

EDIT:

B4X:
Dim i As Intent
    i.Initialize("android.settings.BLUETOOTH_SETTINGS", "")
    StartActivity(i)

Found the code to go to the settings screen.
Change BLUETOOTH_SETTINGS with any code in this link.
 
Last edited:
Upvote 0
Top