Android Tutorial Android Serial tutorial

Discussion in 'Tutorials & Examples' started by Erel, Dec 15, 2010.

Similar threads

B4A Question Bluetooth reception problem
B4A Example Use a handheld Bluetooth scanner via SPP mode
B4A Tutorial Text files
B4A Question Bluetooth App Locking
B4A Question Please help me.
  1. Erel

    Erel Administrator Staff Member Licensed User

    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.


    [​IMG]

    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.

    Code:
    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
    The next Sub running is Activity_Resume:
    Code:
    Sub Activity_Resume
        
    If Serial1.IsEnabled = False Then
            
    Msgbox("Please enable Bluetooth.""")
        
    Else
            Serial1.Listen 
    'listen for incoming connections
        End If
    End Sub
    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:

    [​IMG]

    Code:
    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 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.

    Code:
    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
    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:
    Code:
    Sub btnSend_Click
        
    If connected Then
            TextWriter1.WriteLine(txtSend.Text)
            TextWriter1.Flush
            txtSend.Text = 
    ""
        
    End If
    End Sub
    '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:
    Code:
    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
    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:
    [​IMG]

    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.
     

    Attached Files:

    Last edited: Apr 4, 2018
    vv3g, koaunglay, Yassou and 2 others like this.
  2. schimanski

    schimanski Well-Known Member Licensed User

    Hello Erel! I think, that it is a very useful lib,thanks for that.

    I have tow additional questions about that:

    - The free market GPS-Software connects normally with the internal GPS- Chip. But what's happen, if I have an external GPS. Is in premium navigation-apps like copilot or navgear (I don't have one yet) an option for choosing the gps-serial-port?

    - Can we only init a bluetooth-port with the serial-lib or is it possible to create two virtual ports on one device to send data from the first to the second like a virtual null modem emulator?

    Rgds

    schimanski
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    I don't know.

    You cannot use it this way.
     
  4. Cor

    Cor Active Member Licensed User

    Error: discovery failed java error

    When trying to connect to a device which is not available but showed in the list as a device

    i get an java error on device:
    java.io.IOException:Service discovery failed
    because it's trying to connect in background

    try catch will not help

    How to catch the exception?

    Code:
    Try
      Serial1.Connect(PairedDevices.Get(l.Get(res))) 
    'convert the name to mac address
    Catch
    Msgbox(LastException.Message, "Error connecting.")
    End Try
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    Are you sure that it is not the msgbox displaying the error?
     
  6. Cor

    Cor Active Member Licensed User

    Your are correct, i was fooled by the java message?

    It's is a messagebox

    grCor
     
  7. sinktoma

    sinktoma New Member Licensed User

    Terminal sample works not good

    Hi, I tested your Serial terminal.
    Program finds bluetooth devices and connects to them.
    The Hyper terminal on other computer shows received data, but
    when i sending data to HTC, the "Serial termilal" software are a halts.
    Yes sometimes some data are received, but after time apears timeout Error.

    Firs time i instaled test software it was workinq fast about 3 minutes, but later halted.

    where is the problem?
    The paltform:
    HTC desire, Android 2.2

    Thank you
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    Code:
    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 code reads all text until it finds an end of line character (chr(10)). Maybe you are sending a string without an end of line character?
     
  9. andreas

    andreas Member Licensed User

    Unicode characters in TextReader/TextWriter

    Hi,

    I'm trying to send/recieve Greek characters (Unicode characters) with Serial1 object via TextReader1 and TextWriter1 but the app stop working on phone.

    I used the Erel's example taken from this thread.
    I have made the following changes in "Sub Serial1_Connected()"
    From :
    TextReader1.Initialize(Serial1.InputStream)
    TextWriter1.Initialize(Serial1.OutputStream)
    To:
    TextReader1.Initialize2(Serial1.InputStream ,"UNICODE")
    TextWriter1.Initialize2(Serial1.OutputStream, "UNICODE")

    Code:
    Sub Serial1_Connected (Success As Boolean)
       
    If Success Then
          
    ToastMessageShow("Connected successfully"False)
          TextReader1.Initialize2(Serial1.InputStream ,
    "UNICODE")
          TextWriter1.Initialize2(Serial1.OutputStream, 
    "UNICODE")
          timer1.Enabled = 
    True
          connected = 
    True
       
    Else
          connected = 
    False
          Timer1.Enabled = 
    False
          
    Msgbox(LastException.Message, "Error connecting.")
       
    End If
    End Sub
    At the Encoding parametr of Initialize2, I tested values like UTF8,UTF7 and ANSI and all goes ok. But when i change to "UNICODE" the app halts (the previus Toastmessage remaines infinitely).

    The only I want is to send Unicode characters via BlueTooth.
    Any idea?
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    You should probably use UTF8. It is a Unicode encoding. I don't think that "UNICODE" is a valid value.
     
  11. andreas

    andreas Member Licensed User

    Thank you Erel for your respone. You are right.
    The "TextReader1.Initialize(Serial1.InputStream)" is ok.
    The property was wrong from the computer side.
    Thank you
     
  12. marcode

    marcode New Member Licensed User

    hi, new basic4android customer.

    trying this sample and getting this exact same error. how exactly was this resolved?

    thanks in advance....
     
  13. Erel

    Erel Administrator Staff Member Licensed User

  14. cmartins

    cmartins Member Licensed User

    Erel,

    By using the serial example it works fine. then I disconnect and make the connection again and it works well, but if I try again the same procedure I get the message "java.io.IOException:Service discovery failed", or if the application loses focus.

    When I get this error. I try to disable and enable the BT service, but it freeze. only restarting the cell phone to connect again.

    I tried to use connect and connect3.

    How can I solve it?

    thanks in advance
     
    Last edited: Jun 29, 2011
  15. Erel

    Erel Administrator Staff Member Licensed User

    Which device are you using? Are you calling Serial.Disconnect before creating a new connection?
     
  16. cmartins

    cmartins Member Licensed User

    device: motorola quench

    Yes, I am disconnecting before connect again
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    You can try to comment Serial1.Listen and only use Bluetooth to connect as a client.
     
  18. defillo

    defillo Member Licensed User

    Unable to start Service Discover

    Always get this error

    java.io.IOException: unable to start service discovery

    devices paired, service SPP installed over pc, phone is an HTC Desire Z running android 2.2.1

    any suggestion?
     
  19. Erel

    Erel Administrator Staff Member Licensed User

    Did you try to comment Serial1.Listen? Serial.Connect3 instead if Serial.Connect?

    The serial library was tested on a HTC Desire and it worked without any special issues.
     
  20. defillo

    defillo Member Licensed User

    better

    looks better, but unable to exchange data with a pc, spp service recognized on com4 (in this case)
    maybe it is a pc s.o. problem, I'll check..
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice