Android Tutorial Android Bluetooth / BluetoothAdmin Tutorial

Status
Not open for further replies.
Better implementation based on B4XPages:
Tutorial was rewritten in April 2018.
We will create a chat example between two Android devices.

All the non-UI code is implemented in a class named BluetoothManager. It is initialized in Service_Create of the starter service.

It is always better to implement communication related code in a service or a class initialized from a service. This way the communication state is not affected by the activities more complicated state.

The activities call the class methods directly. Calling the activities subs is done with CallSub. Remember that CallSub doesn't do anything if the activity is paused.

The first activity, the main activity, shows two buttons. One for searching other devices and one for listening for connections.

Searching other devices requires a "dangerous" permissions (see the runtime permissions tutorial for more information).
Note that you need to add the permission in the manifest editor:
B4X:
AddPermission(android.permission.ACCESS_FINE_LOCATION)

B4X:
Sub btnSearchForDevices_Click
   rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
   If Result = False Then
       ToastMessageShow("No permission...", False)
       Return
   End If
   Starter.Manager.SearchForDevices
End Sub

The second button sends an intent to the OS to make the device discoverable and then calls Serial.Listen.

Once a connection is established:
1. AsyncStreams is initialized in prefix mode (see the AsyncStreams tutorial for more information).
2. The ChatActivity is started.

SS-2018-04-04_12.02.01.jpg


Notes

- In this example we send text messages. Use B4XSerializator to send more complex types.
 

Attachments

  • Bluetooth.zip
    12.4 KB · Views: 7,033
Last edited:

irda

Member
Licensed User
Longtime User
"Connection refused". But if I use the function "ConnectInsecure" it works perfectly but the first time I receive the data always lost a couple of bytes.
 

irda

Member
Licensed User
Longtime User
My apologies, I'm a newbie. Attach the code that works for arduino bluetooth adapters and bluetooth BT0417 based chips. This should solve the problem of Terwerlu.


B4X:
Sub Admin_DiscoveryFinished
   ProgressDialogHide
   If foundDevices.Size = 0 Then
      ToastMessageShow("Sin dispositivos encontrados.", True)
   Else
      Dim l As List
      l.Initialize
      For i = 0 To foundDevices.Size - 1
         Dim nm As NameAndMac
         nm = foundDevices.Get(i)
         l.Add(nm.Name)
      Next
      Dim res As Int
      res = InputList(l, "Selecciona dispositivo de conexión", -1)
      If res <> DialogResponse.CANCEL Then
         connectedDevice = foundDevices.Get(res)
         ProgressDialogShow("Intentando conectar a: " & connectedDevice.Name & " (" & connectedDevice.Mac & ")")
         'PuertoBlue.Connect(connectedDevice.Mac)  ===> = Connection Refused
         PuertoBlue.ConnectInsecure(admin, connectedDevice.Mac, 1)  'Works on Arduino BT modules
      End If
   End If
End Sub

Is there some form of connection without the user having to put the pin every time you make the connection? By code I mean.
 

figorra

Member
Licensed User
Longtime User
Serial computer error....

I try to connect to my computer with the program, but I receive teh error in connection java.io.ioException: Service Discovery Failed.


Any idea? :sign0085:

My phone is LG model E610V with android 4.0.3

I load the program, click on search, found 2 devices (the same) and when I select show that error.

Kiko
 

figorra

Member
Licensed User
Longtime User
If I understand correctly then your problem is not related to this thread. Are you sure that B4A-Bridge is listening to Bluetooth connections?

I test directly to my phone with APK file sending and installed on my mobile.

The problem is directly with the REAL phone, no with the AVD.... I'm a newbie in this questions.

For this reason I send my mobile model, etc... and I don't know if is for a adroid sdk version or whatever.

I ask for people what have the same problem.

thx
 

figorra

Member
Licensed User
Longtime User
I test directly to my phone with APK file sending and installed on my mobile.

The problem is directly with the REAL phone, no with the AVD.... I'm a newbie in this questions.

For this reason I send my mobile model, etc... and I don't know if is for a adroid sdk version or whatever.

I ask for people what have the same problem.

thx

I just intall the bridge in my mobile..... same results......
 

Vader

Well-Known Member
Licensed User
Longtime User
Erel,

I want to send an arbitrary number of bytes to the serial port, and then at a time of my choosing go and see if any bytes have been received.

I want to poll the serial port, not wait for an event to signal when to receive the data.

Periodically I will go and send more data, and then again, at a time of my choosing, see if there is any data on the port waiting to be read.

What is the correct library, and do you have any hints on how to do this?

Dave
 

irda

Member
Licensed User
Longtime User
How can I check the status of the buffer? I don't see any property to do so, and I have another problem.

I'm using asyncStreams, I want to send an array of strings and expect a response between each string send, but does not launch the event "AStream_NewData (Buffer () As Byte)" until the send function does not end.

I tried to put a DoEvents but neither works. Can receive data without having to wait for it to end the show?

Simplified code:

B4X:
Sub SendStringAndWaitResponse(StringArrays() As String)
Try
    
    For i = 0 To VectorTramas.Length - 1
        mvarLastString = ""
        'send string
         AStream.Write(VectorTramas(i).getBytes("UTF8") )
    Do While mvarLastString = ""
             DoEvents  
             'At this point I hope the program throw the "AstreamNewData"
             ' event, but nothings happens.

             'code to exit if I wait more than x seconds ---
 
             ' -------------------------------------------
          loop
    Next 
    CheckLastString(mvarLastString)
      
    Catch 
            Log(LastException)   
    End Try
End Sub

'The event only raised when de before sub ends
Sub AStream_NewData (Buffer() As Byte)
   mvarLastString =  BytesToString(Buffer, 0, Buffer.Length, "UTF8")
End Sub

Its not possible without threads?

Lot of thanks.
 

Vader

Well-Known Member
Licensed User
Longtime User
I don't believe you can do this. This is exactly the same problem I have been having.

If I understand correctly, to get this to work you should have a timer that periodically checks a variable for it's content.

The content is updated by the New Data event handler.

If you use DoEvents within a loop in the main thread, the event handler will never process the new data event (as the processor is too busy inside your DoEvents loop), and you will not receive the data.

Edit: Yes I too am underwhelmed by the way it works.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is not possible to pause the main thread. You also do not need a timer. A timer will only make things more complicated.

If you need to wait for the response before sending the next string then you should follow these steps:

You should send the first string. Then in NewData event read the response and send the next string.

You can use a List with the strings that you need to send and then send the next item each time in NewData event.
 

Vader

Well-Known Member
Licensed User
Longtime User
Ok, so this is what I need to do...

On options screen, choose a number of commands to send. Each Command represents some data to send/receive.

Once up to 20 commands have been selected, then compose and send the Command string.

Now, we have to receive and display the data. So, receive one set of data, draw and display the data (some will be graphed), then receive the next set of data, graph and display, etc.

At some point we will decide to send a stop to cancel the current data stream. Then we may want to compose a new set of commands, and then start over.

This is basically what I need to do, and is the only reason I bought B4a. If anyone can help me out, then I would be very grateful.

The above application is a car diagnostic / data logging application. And before anyone suggests I use OBD2, the car is not OBD2 compliant.

Anyone?
 

rajughade2006

Member
Licensed User
Longtime User
Is it possible to call the New Data event from another event, say button press?
For Ex. I want to receive New Data under a specific pattern, so, if I press a button, the new data event can be used in a loop to create an array. i have different types of data coming in for different types of buttons i press and would like to classify the data that way and use the array i made in the loop for other purposes.
Is this valid, or even possible?

Regards,
Raj.
 
Status
Not open for further replies.
Top