I'm trying to create a server on android that will listen on incoming connections ,such as a specific headset i have.
I've read many tutorials, posts in StackOverflow and the one from Android|Developer , and i don't seem to understand a few things .
1) UUID , is it a specific address for each Bluetooth device ? or is it a shared key that need to be in the server and the client in order to create a connection ? my guess is the latter cause there the MAC address as well ...
2) When i pair my Headset with my phone , does the headset saves the MAC\UUID of the last paired device ?
3) Does the Bluetooth chips even works in that way ? The phone connects immediately to a paired device as it turned on, So my guess is that it opens a Socket for each paired device and waits for it to turn on , is that true ?
4) Is it possible to accomplish what im trying ? Meaning creating a BluetoothServerSocket that will accept a connection from the head set ?
code example for the server side:
//This may b needs to be the UUID of the headset ? or special one ? or what ?
UUID myUUID = UUID.fromString("0000111e-0000-1000-8000-00805f9b34fb");
private final BluetoothServerSocket mServerSocket;
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(Activity.APP_NAME, myUUID);
mServerScooket = tmp;
//Im hoping that this will block until the specific headset will be turned on
socket = mServerSocket.accept();
Thanks in advance.
1) UUID ,is a specific ID for Bluetooth communication. When you create your bluetooth socket in Android, listenUsingRfcommWithServiceRecord(Activity.APP_NAME, myUUID); ask Android to redirect bluetooth connection which match with the UUID to your app.
2) I'm not sure. It depends on the type of connection the headset can make. When you want to use it, do you need to select it in Android, or you can just put it and it works ?
3) I don't know. But you can have a look to Android source code ;)
4) If the bluetooth headset can create a connect socket, yes, it is possible
Hope this helps ;)
1) yes UUID is specific to each device and in order to connect to a device you need to have its UUID.
as shown in the Bluetooth chat example by Android SDK
2) depends on the hardware for example
chip sets like the HC-06 does saves the last paired device UUID
while the HC-05 dose not ...
3) The headsets that Ive tested (Samsung made) Acts as a server.
so by initiating a BluetoothSocket with the UUID of the headphone u can connect to it.
4) Yes it is possible to connect to a Bluetooth head set answered in the post : Using the Android RecognizerIntent with a bluetooth headset
Special notes :
Best way to listen to oncoming connections without any wakelocks that I found is by registering the BluetoothDevice.ACTION_ACL_CONNECTED Broadcast and check the name\mac\UUID of each incomming connection.
Thanks to Hoan Nagayu for the help.
Related
It's let me confused for a long time.
I have two bt audio devices connected on android phone, and I want to switch specific bt audio device using programmatically.
I search keyword about a2dp, media router and audioManager than seems can't do this thing...
I only way found the function is:
BT devices=> A and B connected on an Android phone.
And right now the media play to A and I want to switch to B
Step1: A, B unpair on Android phone.
Step2: A pair on Android phone.
Step3: B pair on Android phone.
The media play output is B,
seems lastest pair Bluetooth device is media play output.
Can anyone give me some advice or direction?
Thanks, guys
Documentation says it can only be connected to a single A2DP device at a time, so you should be able to switch between devices by connecting to device you want to use.
You can connect to device by using BluetoothSockets.
EDIT:
I found other solutions, one which I find reliable. Both of them rely on method reflections.
First one is from this post.
1. Get BluetoothA2dp proxy from serviceListener
bluetoothManager.adapter.getProfileProxy(this, serviceListener, BluetoothProfile.A2DP)
private val serviceListener = object : BluetoothProfile.ServiceListener {
override fun onServiceDisconnected(profile: Int) {
if (profile == BluetoothProfile.A2DP) {
bluetoothA2dp = null
}
}
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) {
if (profile == BluetoothProfile.A2DP) {
handler.post(btSearchRunnable)
bluetoothA2dp = proxy as BluetoothA2dp
}
}
}
Get "connect" method from reflection.
private val connect = BluetoothA2dp::class.java.getDeclaredMethod("connect",BluetoothDevice::class.java)
Invoke method with proxy as first argument and device as second.
connect.invoke(bluetoothA2dp,device)
Other method used reflection to get createRfcommSocket to circumvent issue with one parameter which you can't normally access. I can post link to it, but problem I had with it is that always lagged main thread, always threw me an error and connected unpredictably.
I'm currently developping my first app in java.
This app requires a direct connection with my BL652, which doesn' t accept any kind of pairing option. That being said, I'm stuck with the code below, which still tries to pair with my bluetooth device instead of just connecting. Therefore, I wanted to know what am i supposed to do in order to make a connection that doesnt require pairing.
Thanks in advance for any response.
String mac_address = "DA:72:21:29:0F:F0";
private static final UUID MY_UUID = UUID.fromString("E54B0002-67F5-479E-8711-B3B99198CE6C");
lvNewDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BluetoothDevice device = (BluetoothDevice) mBluetoothAdapter.getRemoteDevice(mac_address);
try {
socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
} catch (IOException e) {
e.printStackTrace();
}
I'm not sure about connection to external hardware but it's definetly possible to connect 2 phones without pairing. I made it using Android Nearby Connections . And yeah it's basically working with BLE. As far as I know it's possible to connect to RaspberryPi using that API.
Bluetooth devices can be made to communicate with each other using master-slave configuration. I first tried with two BLE-HC05s, made one as master and the other as slave, and as expected the master is able to send data, slave is able to receive data, that can be seen using the Serial Monitor in Arduino IDE. I have developed a similar app, which connects to a BLE-HC05 device, sends and receives data. But since you are trying to get data or send data to the App on your phone, Android will not support such unpaired anonymous communications. If you are having trouble with connection or pairing Bluetooth device and your app, I may help you with that. But as far as Bluetooth communication without pairing is concerned, you may not be able to find a way.
Edit: The code to connect any bluetooth device, like BLE-HC06 as you have mentioned, is 1234 (Only if you have not changed it)
I try to make an app that send a message(String) to another app, I follow the official documentation : https://developer.android.com/guide/topics/connectivity/wifip2p but was too overwhelming because I'm a beginner.I found later a tutorial based on the official documentation but app doesn't work properly, the app crashed.Anyway , I don't want to carry the whole process for making a P2P connection, I just want to send that message for already connected device(manually) , I'm trying something like that but I don't know how:
If CONNECTED_DEVICES is equal to 1
sendMessage("Ana Are Mere");
Else If CONNECTED DEVICES is greater that 1
Toast : "Connect With Only A Device"
Else
Toast : "No Devices Connected"
It's not a very beautiful example, but that's my idea.
I created one simple service in android things to use Bluetooth BLE.when I try to test it with NRF connect app it's visible as "unknown service".I want to give name something like "Speed Service".how would I do it?
This is a factor controlled by the scanning app you are using, not necessarily your Android Things device. Bluetooth LE doesn't send metadata like a "service name" over the air. Services are identified by their UUID alone. If your device implements one of the standard service UUIDs, a scanner app like NRF Connect will probably recognize and display the service type.
As another example, our Bluetooth GATT Server sample implements the standard Current Time Service by using the UUID adopted by the Bluetooth SIG for that service.
private BluetoothAdapter bluetoothAdapter = null;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
void ChangeDeviceName(){
Log.i(LOG, "localdevicename : "+bluetoothAdapter.getName()+" localdeviceAddress : "+bluetoothAdapter.getAddress());
bluetoothAdapter.setName("NewDeviceName");
Log.i(LOG, "localdevicename : "+bluetoothAdapter.getName()+" localdeviceAddress : "+bluetoothAdapter.getAddress());
}
Reference: Change the Android bluetooth device name
Hope this case is similar and of use to you.
Is there a way to programatically identify the currently USB working mode?
I mean, some function that would return either if the device is at Host, Device or Accessory mode.
Not the best answer, but once you have a UsbManager you might be able to figure it out. Usually this UsbManager is created using a Context I believe, but it looks like you are switching modes so you hopefully can get a UsbManager instance, m in this case:
UsbManager m = createManagerSomehow
For accessory mode, this only has one callback. If this returns one then you know it is Accessory.
m.getAccessoryList()
So I'm thinking somehting like this might work:
if(m.getAccessoryList().size() > 0)
accessoryMode = true;
And for Host, if you have a UsbDevice device, or String deviceName you could use the same UsbManager m function to see if it contains that device.
if(m.getDeviceList().containsValue(device))
hostMode = true;
or
if(m.getDeviceList().containsKey(deviceName))
hostMode = true;
and I don't know about what Device is, but if none of the above are true then you know it is just a Device. You don't really need this boolean variable below, because you have the other two. It's just here to help with my explanation via state logic.
if(!hostMode && !accessoryMode)
deviceMode = true
Hope this helps. Check out UsbManager for more documentation and just search the page for Host and Accessory.
http://developer.android.com/reference/android/hardware/usb/UsbManager.html
NOTE: I am a little confused when you say you switch the modes in your comment. It conflicts with the Accessory call I make above and might not work, but what I would do then (if you don't need deviceMode) then just check if the usb device is a HOST mode and if not you know it is in application mode...