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.
Related
I am working on my Bachelor Thesis and I have to implement an application using Google Nearby Connection API. The goal is to develop a disaster assistance app.
I tested Google Nearby Connection for the past two day and I have some problems, quesitons.
I have 6 devices, 4 Motorola G (2nd Generation), 1 Nexus 5X and 1 OnePlus 5T. They all are up to date. I also use the latest version of Google Nearby
'com.google.android.gms:play-services-nearby:15.0.1'
Here are my questions:
The Motorola devices ask for a pairing code to connect one to another, but even when the pairing is accepted they do not connect.
Some device connect flawlessely (OnePlus and Nexus) but the Motorola have problems connecting, the often throw this error : STATUS_BLUETOOTH_ERROR
Is it possible to create a mesh application that will forward message form device to device? With the testing I made I am starting to wonder if that's really feasable.
During my testing I often discover and advertise in the same time. Is there a better way to do so that might avoid problems?
I used the documentation of google and some other ressources I found online.
Here is the code I had at the end: Gist Link
Thank's a lot for the help guys!
Disaster assistance apps have actually been talked about a lot on our team, as a really interesting use-case. I work on Nearby, the team that built (and maintains) Nearby Connections. It's definitely feasible, once you know the limitations.
I believe that Motorola bug has been fixed on our internal builds, so look out for it in the coming months. The update will be pushed out to all devices (you don't need to update your app) in 1.5~2 months. Wish we could push it faster, but it is what it is. They should be connecting if the pairing dialog is accepted, though. If that's not working, I unfortunately don't have a work-around.
We've found that toggling Bluetooth is the best way to get around STATUS_BLUETOOTH_ERROR, as the radio can get into a bad state (especially on Android versions older than N... which is... a lot of Android versions...). We do our best to toggle semi-often, by toggling the radio after apps stop using Nearby Connections, but sometimes that's not enough. In extreme cases, the phone may have to be rebooted. This error can also go away on it's own, and can also be somewhat alleviated by stopping discovery before connecting.
Yup, meshes are definitely possible. For an always connected mesh, you'll want to use P2P_CLUSTER. Try to keep 3~4 simultaneous connections per device (and have some kind of logic to avoid forming islands). Once the devices are connected, you'll need to build a protocol to send messages, flooding the network for broadcasts or hoping between nodes for directed messages. Other ways to solve this problem that I've seen are using advertise / discovery to transmit short pieces of information asynchronously, or setting up a timer (eg: Once an hour, everyone scans and tries to connect to exchange data, and then quickly disconnects), or forming a 'snake-like' connection where everyone connects to at-most 2 devices and forms a long string of connections.
Advertising is usually lightweight, but discovery can be hard on the radio. We turn it off internally while you connect, but we turn it back on for the duration of the connection. This can lead to flaky connections. If you're able, try to limit discovery to short bursts.
PS: You can check my post history to get some more in depth information about Nearby Connections.
PPS: In the future, break up your stack overflow questions into smaller, more pointed questions. It's more helpful for people searching in the future.
I wanted to experiment a bit with an old bluetooth device and my smartphone. The device uses the Bluetooth 3.0's unicast connectionless mode to send data. I'd like to read this data with my smartphone, without establishing a connection. Reason? The device has a big range of about 50 meters, the smartphone only about 10 meters. I'd like to receive the data even if I am further away than 10 meters. Is it possible?
I googled on the topic and I found somewhere in the API some mysterious constants definitions "L2CAP" or so, with a comment "Unicast connectionless mode", which means, there seems to be a support for this feature. But except of those constants I found nothing - no functions, classes, methods, examples.
I would be thankful for any advice.
Unfortunately L2CAP is not supported version 4.2 onwards, there is an open issue on Android website which have more details.
Issue 58164: Support Bluetooth L2CAP
There seem to be no response on when fix will be done. I am too waiting for fix :-(
Currently I have a question about using Android Wifi, Bluetooth APIs together.
(Please be noted that it's a problem on app development, not for a normal user guide)
I have a trouble when search device' services via Wifi at the same time with searching device via Bluetooth.
For more info:
On wifi search, I use Bonjour protocol (an Apple's implement of Zeroconf which can help locating services that local network devices offer). The Java implement that I use is jmdns. During the search session, I create a MulticastLock in order to receive multicast packages of Bonjour.
On bluetooth search, I just use BluetoothAdapter together with BroadcastReceiver to get bluetooth device info.
Problem happens to the search result, whenever two search sessions above are executed at the same time, mysearch result on Bonjour (Wifi) search has never get enough like it does when only it is executed.
Ex: Bonjour search just gets 1 instead of 2 device' services when search together with Bluetooth. Bluetooth search result is always enough, however.
This is tried many times and I surely confirm that there is nothing related to network' strength problems.
Has anyone met this problem yet?
Even if your situation is about using Wifi together with Bluetooth, any experiences or guests are very helpful to me!
Khoi.
I am doing pretty much the same stuff you are doing.
My experience differs in that:
I do not use Bluetooth discovery, as I know what device I want to connect to. I just initiate a client connection.
I use Asynctasks for background operations. What are you using?
Two possible issues:
Multiple Asynctasks not executing in parallel due to Android faulty implementation. I have had a similar bug after setting my Android API target to the latest SDK (as it is best practice). Now, after API13, Android Asynctask implementation changed and tasks are NO LONGER executed in parallel (so my wifi thread never started for example, if bluetooth thread was running!!!). The fix is to put a couple of lines of code to make the default executor parallel again, or to just use API11 or lower as target version. See this thread for details.
OverTheAir interference between the 2. Bluetooth discovery is, to my knowledge, the most expensive operation you could do on Bluetooth. So that 2.4GHz multi-purpose chip may be swamped over the air. Internally it has coexistence between WiFi and BT. Remember the WiFi and Bluetooth channels over the 2.4GHz overlap. So what I am saying doing discovery over the same main frequency at the same time might not work that great. You should investigate that...
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
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.