The code in this tutorial should not be used for new projects.
New tutorial: https://www.b4x.com/android/forum/threads/android-bluetooth-bluetoothadmin-tutorial.14768/#content
This tutorial covers the Serial library. This library allows you to connect with other Bluetooth devices using virtual serial ports (RFCOMM).
The Serial library requires Android OS 2.0 or above (API level 5 or above).
We will build a simple chat example which allows two connected devices to send text messages.
We created a process global object named Serial1 of type Serial.
Usually it is a good idea to initialize process objects in Sub Activity_Create when FirstTime is True. This way the objects will be initialized exactly once.
The next Sub running is Activity_Resume:
Here we are checking if the Bluetooth device is enabled. If it is not enabled we ask the user to enable it. Note that by putting this code in Activity_Resume (and not Activity_Create) this test will happen every time the activity is resumed. So if the user goes to the settings screen, enables the device and then returns to our application we will now know that the Bluetooth is enabled.
If the Bluetooth is enabled we start listening for incoming connections. This allows other devices to connect with our device. This is not required if you connect to a device that listens for connections (like external GPS for example).
Note that calling Listen more than once doesn't do anything. So we are safe calling it this way.
When the user presses on the Connect menu item we show the user the list of known paired devices. When the user clicks on a device name we fetch its MAC address from the map and connect to it:
The connection is not established immediately. It will happen in the background. When the connection is established, the Connected event will be raised. A 'Success' parameter tells us if the connection is successful.
The Connected event can also be raised if an incoming connection is established.
If the connection was established successfully we can start the data transfer.
TextReader1 and TextWriter1 are process global object. We now initialize them using the serial stream. This will allow us to send and receive text over our newly created connection.
Timer1 is used to test whether there is incoming data (and read this data). Now we enable it and start listening.
If the connection is not successful we retrieve the exception and show it.
Sending messages - When the user presses on btnSend we send the text:
'connected' is a variable that we use to know if we are currently connected.
Note that we call Flush after writing the text. This way we make sure that TextWriter doesn't buffer the text and sends it right away.
Receiving messages - Whenever the timer ticks we check if there is any data waiting to be read. If there is, we read it and add it to the large EditText:
TextReader.ReadLine is a blocking call. It waits till there is at least a single character to be read. Therefore we need to test TextReader.Ready if we don't want to block our application.
This application can also be used to connect with non-Android devices.
An external GPS for example:
The external GPS continuously sends its data as text.
I actually had quite an interesting conversation with the external GPS...
The program is attached.
Edit: It is recommended to use the new AsnycStreams object instead of polling the available bytes parameter with a timer. Using AsyncStreams is simpler and more reliable.
New tutorial: https://www.b4x.com/android/forum/threads/android-bluetooth-bluetoothadmin-tutorial.14768/#content
This tutorial covers the Serial library. This library allows you to connect with other Bluetooth devices using virtual serial ports (RFCOMM).
The Serial library requires Android OS 2.0 or above (API level 5 or above).
We will build a simple chat example which allows two connected devices to send text messages.
We created a process global object named Serial1 of type Serial.
Usually it is a good idea to initialize process objects in Sub Activity_Create when FirstTime is True. This way the objects will be initialized exactly once.
B4X:
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
Serial1.Initialize("Serial1")
Timer1.Initialize("Timer1", 200)
End If
Activity.LoadLayout("1")
Activity.AddMenuItem("Connect", "mnuConnect")
Activity.AddMenuItem("Disconnect", "mnuDisconnect")
End Sub
B4X:
Sub Activity_Resume
If Serial1.IsEnabled = False Then
Msgbox("Please enable Bluetooth.", "")
Else
Serial1.Listen 'listen for incoming connections
End If
End Sub
If the Bluetooth is enabled we start listening for incoming connections. This allows other devices to connect with our device. This is not required if you connect to a device that listens for connections (like external GPS for example).
Note that calling Listen more than once doesn't do anything. So we are safe calling it this way.
When the user presses on the Connect menu item we show the user the list of known paired devices. When the user clicks on a device name we fetch its MAC address from the map and connect to it:
B4X:
Sub mnuConnect_Click
Dim PairedDevices As Map
PairedDevices = Serial1.GetPairedDevices
Dim l As List
l.Initialize
For i = 0 To PairedDevices.Size - 1
l.Add(PairedDevices.GetKeyAt(i)) 'add the friendly name to the list
Next
Dim res As Int
res = InputList(l, "Choose device", -1) 'show list with paired devices
If res <> DialogResponse.CANCEL Then
Serial1.Connect(PairedDevices.Get(l.Get(res))) 'convert the name to mac address
End If
End Sub
The Connected event can also be raised if an incoming connection is established.
B4X:
Sub Serial1_Connected (Success As Boolean)
If Success Then
ToastMessageShow("Connected successfully", False)
TextReader1.Initialize(Serial1.InputStream)
TextWriter1.Initialize(Serial1.OutputStream)
timer1.Enabled = True
connected = True
Else
connected = False
Timer1.Enabled = False
Msgbox(LastException.Message, "Error connecting.")
End If
End Sub
TextReader1 and TextWriter1 are process global object. We now initialize them using the serial stream. This will allow us to send and receive text over our newly created connection.
Timer1 is used to test whether there is incoming data (and read this data). Now we enable it and start listening.
If the connection is not successful we retrieve the exception and show it.
Sending messages - When the user presses on btnSend we send the text:
B4X:
Sub btnSend_Click
If connected Then
TextWriter1.WriteLine(txtSend.Text)
TextWriter1.Flush
txtSend.Text = ""
End If
End Sub
Note that we call Flush after writing the text. This way we make sure that TextWriter doesn't buffer the text and sends it right away.
Receiving messages - Whenever the timer ticks we check if there is any data waiting to be read. If there is, we read it and add it to the large EditText:
B4X:
Sub Timer1_Tick
If connected Then
If TextReader1.Ready Then 'check if there is any data waiting to be read
txtLog.Text = txtLog.Text & TextReader1.ReadLine & CRLF
txtLog.SelectionStart = txtLog.Text.Length
End If
End If
End Sub
This application can also be used to connect with non-Android devices.
An external GPS for example:
The external GPS continuously sends its data as text.
I actually had quite an interesting conversation with the external GPS...
The program is attached.
Edit: It is recommended to use the new AsnycStreams object instead of polling the available bytes parameter with a timer. Using AsyncStreams is simpler and more reliable.
Attachments
Last edited: