As a beginner in Android programming I have a question:
I want to receive data (two bytes) from a bluetooth/serial module connected to a microprocessor. This data should be printed to the screen and updated say once per second. I found this already: How to prevent Android bluetooth RFCOMM connection from dying immediately after .connect()?
Which should be a working code but nothing is happening.
I changed the mac address to 00:11:12:05:03:67, which should correspond with my bluetooth module.
Am I heading completely in the wrong direction with this? I guess what I want is quite basic: just a simple one way data transmission over bluetooth.
Any thoughts will be very much appreciated.
Best wishes,
Kevin
The question you've referred to there is very useful as it provides a workaround for a situation where the usual call to .createRfcommSocketToServiceRecord() fails to work. I have personally used that workaround solution in a project I'm doing right now. What I do is I attempt the .createRfcommSocketToServiceRecord() call first, and if that fails, my code then attempts to connect with the .getClass().getMethod("createRfcommSocket", new Class[]{int.class}); workaround. Having experimented with a number of Bluetooth-to-serial PCBs, some of them tend to be a bit 'awkward' and the latter reflection method works when the .createRfcommSocketToServiceRecord() does not.
However... although that question you referenced does provide a very useful compact piece of code, I don't think it's the best place for you to start. The place you should start is at Android's Bluetooth documentation, which explains the whole process extremely well, including how to use separate Threads to handle discovery, connection, etc. In fact it's really easy to get started using the Bluetooth Chat source code. Using that, you can get up and running and connected to a Bluetooth-serial module very quickly. You just need to make sure you change the UUID to that required for Serial Port Profile (SPP):
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
That will hopefully be enough to have a simple application that will talk to your Bluetooth serial module. The Bluetooth Chat example application also provides you with dialogs that handle device discovery, pairing, and all that good stuff, so you don't have to mess about hard-coding in your device's MAC address like you have been.
If you have problems connecting then you need to be specific about what's actually happening; i.e., what exceptions you're getting, and so forth.
Related
I have read many, many SO questions and answers about this topic but none seem to work completely. The 3 most detailed answers I have found are:
Using the Android RecognizerIntent with a bluetooth headset
Programmtically connect to bluetooth headset from android app
bluetooth pair and connect device
Which references : https://github.com/giladHaimov/BTWiz
all of which are now quite old and have had no further discussion in some time.
and the Bluetooth chat example from the sdk. - compiles and works as a text chat example, but after modification I can not get it to create a connection to any headsets.
I have followed the above 3 examples and worked through the code and customized them to my application - adding extra variable references as required. Most if not all examples seem have major errors and are only pointers. I am not asking for "you email me complete working code", but there is enough missing from all the answer that the missing part can not be felt in the dark.
I have also downloaded the HSP and HFP and SPP and RFCOMM Bluetooth specifications docs. These are even more vague. They say "create a connection".. but don't indicate how... I understand they are trying to be OS/language agnostic... but ouch!!
I am able to get as far as a broadcast receiver or listener acknowledging the creation of a new connection, but there seems to be a gap between that point and getting a functional SCO audio connection.
After creation of the connection, looking at the built in BT manager app, the headset doesn't show as connected at all.. so this must be a low level connect (ACL) and not a high level connection.
I understand that each persons approach to programming a solution is different, but the underlying issue remains the same. Some are low level and close to the OS, others have a high degree of abstraction and referencing high level objects which perform the low level work.
Is anyone able to shed some light on the necessary steps to get from an ACL connection to a functional audio connection please?
I can post code examples later if requested.
I am working on a project where I need to transfer data between android and raspberry pi via Bluetooth. However, I am new to this and I don't have deep understanding on what happens when two devices are paired. Based on assumption that the two devices of interest are already paired, where would the starting point be for programming for such task? I've been reading on BluetoothSocket, but I am still unsure of where to start. Can anyone help me please?
Thank you so much in advance!
I have been looking into this same issue, here is the reading I found on my end. I was looking to specifically code in python so that's the angle of the first one, the second is C++, but has a really thorough intro.
https://people.csail.mit.edu/albert/bluez-intro/index.html
and this one is really good too, the intro isnt too dense:
http://beej.us/guide/bgnet/output/html/multipage/index.html
The specific parts to look at involve the planning aspect. The intro of the beej programming guide shows specifically what sockets are and how they fit in a network sense. This means streaming sockets and datagram sockets. It also shows which of the sockets are used and which are availible. Chapters 1 through 3 gave me a solid enough reading basis to use the second document to determine a few things.
Chapter 2 of the MIT document goes into specific detail about each of the steps that must occur at a structural level including L2CAP + UDT, RCOMM, and whatever the stream one was. From reading these I was able to determine that the network I wanted to use was an L2CAP. I hope these help point you in the right direction though as far as what network you want to setup and what language you want to program in.
I've been working on the same task little while ago. The point is, that in order to start sending and receiving data you have to establish connection first. There is two side- device which connects (creates socket) and the other receiving connection (bluetooth server socket), giving out connection once connection is complete. After connection is established, you should stop receiving incoming connection or attempting establishing any connections.
From implementation perspective, you should implement few threads for managing all those stages - connection thread, accept thread, communucation thread. There is a great example from Google: https://github.com/googlesamples/android-BluetoothChat . It uses that technic. The only drawback is that it uses Handler (Android feature, allowing thereads to communicate) for informing user about Bluetooth events. I modified it a bit by introducing another thread, receiving status updates and calling methods from callback interface, feel free to use code from project: https://github.com/AlexShutov/LEDLights.
I am writing an Android App that connects and communicates with a peripheral over BLE. I've been around the bases a few times on BLE development, with iOS and firmware and now android, and the doc always seems to advise you to:
connect
discover services
(on some stacks, not android) a second round of discovery for characteristics within services
save references to the characteristics
read and write to characteristics (or subscribe to notifications) as you wish
In the back of my mind, I've always wondered if one can skip the discovery step? Say if its a situation where you are dead certain what you are talking to, and you know the UUIDs and properties of all services and attributes provided by the peripheral. Can my app just presumptively create my own BluetoothGattCharacteristic objects with UUIDs and properties, and read /write to them, and the stack will just send the corresponding commands, without having gone through that initial interogation?
Then, on this project that thought was forced to the front of my mind, because we are having some mysterious glitch/corruption in the discovery response -- on some phones it would publish services, but no peripherals. It is intermittent and we are sure it is due to some weirdness in the peripheral firmware or configuration, but unfortunately we can't wait for them to fix their problem. So I decided to test out the above theory, with some success:
I built in a secondary path that, in this event, would create BluetoothGattCharacteristic objects with the correct UUIDs and properties and attach them to the received service object. And lo and behold... it worked! Sort of. I could read and write to about 25 of the 28 characteristics... not sure yet what's wrong with the other three. But this seems to me to be a promising result w.r.t. my theory above!
So my question is, is my theory true? Can I skip discovery? If so, is there any sample code or guidance on how to do this, how to correctly set up your presumptive service and characteristic objects outside of the context of a discovery response? (Since I'm obviously close, batting 25/28=0.893, but no cigar.)
Would appreciate any pointers to discussion on this topic, and esp to any sample code, projects, or snippets.
Is it possible to set up the Android Bluetooth Chat sample app to connect more than one person at a time, and have a mini chat room? What would that entail?
tl;dr version: Bluetooth sucks for this, don't use it, use wifi instead, probably backed by a web backend.
I have investigated this issue thoroughly throughout the years in the interests of a social wireless network research project. My general advice is: it doesn't work with more than two / three people. Bluetooth just isn't designed with wireless peer to peer networks in mind.
In general, it seems that the cheap Bluetooth controllers included on Android devices (especially HTC's devices, iirc) don't really handle any more than two or three connections at a time. I'm unsure if this is a hardware or firmware problem, but I can recount some basic anecdotes. I was working to implement this idea at the SDK level (i.e., without firmware modifications) around the beginning of 2011, and was able to get a peer to get two additional connections (i.e., three devices, each connecting to the other two) to work for a period of a few minutes to an hour before the connections would suddenly die and the socket would become unusable, requiring reconnection. Unfortunately, 20 minutes was an upper bound, and generally it was impossible to get connections to more than one other device at all reliably.
The goal of the project was to support multiple people interacting with each other silently in the background, but this never materialized, instead we ditched Bluetooth and went with wifi instead, which worked much much better. In the abstract, I think people view Bluetooth as a possible medium for reliable peer to peer communication, but it wasn't really designed that way: it's more of a medium used for short range communication between small devices (think headsets).
Be aware that if you want to do this, the maximum number of devices to which you can connect is fixed, because as per the Bluetooth spec, a piconet supports a maximum of seven devices. (See the wikipedia article.)
The required change is simple: you use a different UUID for each device. This can be implemented a number of ways, using an out of band exchange mechanism, or simple scheme where you assign UUIDs in an increasing fashion and when connecting to the network, try each in succession.
Here are some relevant Google groups threads:
Bluetooth peer to peer networks
Multiple connections on Android Bluetooth
I remember posting a more elaborate one detailing how to do this (with code) that I might dig up as well.., if I can find it. It should be from late 2010 or early 2011.
So the answer is, in the abstract, yes, you can try to do this, by using multiple UUIDs (after you use one, that's it, and you have to try another using some assignment protocol). However, in practice, after a lot of trial and error, this doesn't really work for what you probably want to use it for, and it's a lot better to go with an internet backend instead. By the way, this is also good for another reason, most users don't really like to turn on their Bluetooth for fear of their battery being drained..
Leaving this here, in case it helps someone else.
I was able to make my custom chat room following official bluetooth tutorial and modifying it a little.
Unfortunately, I cannot provide most of my code, but main idea is:
Every device is acts both as server and as a client. When Chat is started, device starts its server thread. Server thread is the same as official but doesn't ends when accept connection. It just keep listening.
Client thread is identical as in tutorial.
Both server and client thread manages connection same. I created separated threads for accepting messages following this tutorial and one for sending them.
private void manageConnectedSocket(BluetoothSocket socket) {
//create thread responsible for sending messages.
SendingThread w = new SendingThread(socket);
MainActivity.addSendingThread(w);
//Creates listener for messages to accept.
MainActivity.addListener(socket);
}
Now in main activity always when user click send button, for each worker (sending thread) send message to remote device. Listening is running asynchronously.
IMPORTANT:
You need to handle exceptions when message send fails and remove sending and recieving thread for device when you detect it is disconected. In my case I used well known UUID "00001101-0000-1000-8000-00805f9b34fb". For every device.
You need to wait 3 second between atempts to connect as client because some devices has weak bluetooth hardware and it is refusing connect as client.
Bt connection is supporting up to 7 -10 connections. So you will be limited in that range. I think it is designed for extensions of main device and not for random comunication
Source: search "bluetooth programming" on google
Here's the scenario:
I need to write an application for Android to create a RFCOMM socket to a PC with a Bluetooth dongle (I'm going to write the server too).
My requirement is that the user doesn't have to pair device manually.
Actually, with a big hack, I'm using the createInsecureRfcommSocket.
A little scenario: I've an Android application which exchanges information with a Linux box with a RFCOMM socket opened. I can manually set the PIN on the devices (hard coding it IS an option)
I'm looking for different roads:
Write a JNI wrapper
As has been done here by Max Kellermann, I can write a JNI layer to make all the pairing phase. This should be a good option, but there's a problem:
The NDK 4b does not provide libbluetooth libraries, so -lbluetooth fails, as well as the NDK v.3.
Options:
Find the NDK 1.5 (which includes lib bluetooth). After days of web search I've been not able to find out. Anyone has or knows where I can find it?
Compile libbluetooth for Android by myself and use them for -lbluetooth. No lucky there, I'm not able to build them. Any hint?
Use something exposed by the APIs
Any one know how can I use createRfcommSocketToServiceRecord and have the user not to manually pair the device? Is it possible? How should I write the server?
Something I do not know
Maybe (sure!) there is something I do not know. Maybe I can use something else? Not RFCOMM? SDP?
Maybe I can manually pair with the Android API?
I hope to have been clear enough, if not just ask. And again, as it's not the first time, I'm in your hands :)
Thanks for all the support guys!
At the end, I can say that you can't.
Even if you find a way, using wrappers, writing C modules and so on, android evolution will probably change the thing you're using.
And so, there's no option. Sadly.
Let's see how Android Bluetooth API will change in the future.
Yes we can create it Rfcomsocket and listen the socket without user concerns and also without pairing devices.
https://code.tutsplus.com/tutorials/create-a-bluetooth-scanner-with-androids-bluetooth-api--cms-24084
Follow this !!
The Android Bluetooth API is not finalized, and will change. Use at your own risk. This class implements an API to the Bluetooth RFCOMM layer. An RFCOMM socket is similar to a normal socket in that it takes an address and a port number. The difference is of course that the address is a Bluetooth-device address, and the port number is an RFCOMM channel. The API allows for the establishment of listening sockets via methods bind, listen, and accept, as well as for the making of outgoing connections with connect, connectAsync, and waitForAsyncConnect. After constructing a socket, you need to create it and then destroy it when you are done using it. Both create and accept return a FileDescriptor for the actual data. Alternatively, you may call getInputStream and getOutputStream to retrieve the respective streams without going through the FileDescriptor.