Programmatically connect to paired Bluetooth device - android

Is there a way, using the Android SDK, to programmatically connect to an already-paired Bluetooth device?
In other words: I can go into Settings -> Wireless & networks -> Bluetooth settings, and tap the device (listed as "Paired but not connected"), at which point it will connect. I'd like to be able to do this programmatically, but don't see a way to do this.
I see the options to create an RFCOMM socket, and for a SPP device, I'm assuming that'll do the connection part as well, but for an A2DP device, where the actual data transfer will be handled by the OS rather than by my app, I think that's not applicable?

Okay, since this was driving me crazy, I did some digging into the source code and I've found a 100% reliable (at least on my Nexus 4, Android 4.3) solution to connect to a paired A2DP device (such as a headset or Bluetooth audio device). I've published a fully working sample project (easily built with Android Studio) that you can find here on Github.
Essentially, what you need to do is:
Get an instance of the BluetoothAdapter
Using this instance, get a profile proxy for A2DP:
adapter.getProfileProxy (context, listener, BluetoothProfile.A2DP);
where listener is a ServiceListener that will receive a BluetoothProfile in its onServiceConnected() callback (which can be cast to a BluetoothA2dp instance)
Use reflection to acquire the connect(BluetoothDevice) method on the proxy:
Method connect = BluetoothA2dp.class.getDeclaredMethod("connect", BluetoothDevice.class);
Find your BluetoothDevice:
String deviceName = "My_Device_Name";
BluetoothDevice result = null;
Set<BluetoothDevice> devices = adapter.getBondedDevices();
if (devices != null) {
for (BluetoothDevice device : devices) {
if (deviceName.equals(device.getName())) {
result = device;
break;
}
}
}
And invoke the connect() method:
connect.invoke(proxy, result);
Which, at least for me, caused an immediate connection of the device.

the best way I found to solve my problem was finding out that I can create a button that brings up the Bluetooth Settings screen. I didn't realize you could do this, or I would have from the beginning.
startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));

if the device is already paired , then you can use
if(device.getBondState()==device.BOND_BONDED){
Log.d(TAG,device.getName());
//BluetoothSocket mSocket=null;
try {
mSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e1) {
// TODO Auto-generated catch block
Log.d(TAG,"socket not created");
e1.printStackTrace();
}
try{
mSocket.connect();
}
catch(IOException e){
try {
mSocket.close();
Log.d(TAG,"Cannot connect");
} catch (IOException e1) {
Log.d(TAG,"Socket not closed");
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
for the MY_UUID use
private static final UUID MY_UUID = UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB");
the above code snippet is just to connect your device to an A2DP supported device.
I hope it will work.

I used the code here as a starting point for this functionality in my app: http://developer.android.com/guide/topics/wireless/bluetooth.html#ConnectingDevices
Once the device is paired, the app has no problem connecting the two devices together programmtically.

Related

Xamarin bluetooth in Android connection fails

I'm trying to establish a bluetoothconnection to another phoner. Later on, it'll be a board with a HC5 module, but for debugging I'm just using a phone.
The problem is, that connect fails and throws an IO Exception:
" read failed, socket might closed or timeout, read ret: -1"
A quick google-search shows a lot having this problem. The only way I can see it solved, is by using a method not public in the API
Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mmSocket = (BluetoothSocket) m.invoke(mmDevice, 1);
The problem just is, that createRfcommSocket has been removed, and the result from getMethod will be null.
My code is from the example: https://github.com/xamarin/monodroid-samples/tree/master/BluetoothChat which for connecting is:
public ConnectThread(BluetoothDevice device, BluetoothChatService service)
{
UUID MY_UUID = UUID.FromString("00001101-0000-1000-8000-00805f9b34fb");
mmDevice = device;
_service = service;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try
{
if ((int)Android.OS.Build.VERSION.SdkInt >= 10) // Gingerbread 2.3.3 2.3.4
tmp = device.CreateInsecureRfcommSocketToServiceRecord(MY_UUID);
else
tmp = device.CreateRfcommSocketToServiceRecord(MY_UUID);
}
catch (Java.IO.IOException e)
{
Log.Error(TAG, "create() failed", e);
}
mmSocket = tmp;
}
Since the 'original hack' doesn't work, and I haven't found any other solution, I'm hoping somebody here knows how to fix this.
Best regards!
This is the issue I and others in my company have come across when working with Bluetooth devices from Android phones. It is well described on SO here: Service Discovery Failed Exception Using Bluetooth On Android
The method you describe as being removed is, in fact, still operational. And it is the one we have successfully used. We attempt connection using the
tmp = device.CreateRfcommSocketToServiceRecord(MY_UUID);
method you show above.
Use a try...catch block around tmp.Connect() (your code does not show the Connect call)
In the catch block "re-create" the BluetoothSocket using the createRfcommSocket method. I used a small method to do this:
private BluetoothSocket CreateRfcommSocket(BluetoothDevice bTdevice)
{ // This is an "undocumented" call that is needed to (mostly) avoid a Bluetooth Connection error
// introduced in Android v4.2 and higher. It is used as a "fallback" connection.
// Full paths version of code!
//Java.Lang.Reflect.Method mi = device.Class.GetMethod("createRfcommSocket", new Java.Lang.Class[] { Java.Lang.Integer.Type });
//_bluetoothSocket = (BluetoothSocket)mi.Invoke(device, 1);
// Compact version of above
var mi = bTdevice.Class.GetMethod("createRfcommSocket", Integer.Type);
return (BluetoothSocket)mi.Invoke(bTdevice, 1);
}
This is the method indicated here: Xamarin Forum Post
I have tested this on Android 4.4.2 and Android 8.0 and it works on these systems. Another person in the company has tested the Java equivalent code on Android: 4.2.2, 4.4.2, 7.0 and 8.0 and it works in every case.

How to rename Android bluetooth paired device by programmly?

I need to "rename" bluetooth paired device of Android phone with programming. But searching results are most discuss about local bluetooth rename method. And it could use setname() to complete. Does there have any method to rename "paired device" of Android phone ?
I know the question is old, but I just needed this and found out how to do it. It uses reflexion so I'm not sure this is the best way to go but it works.
public void renamePairDevice(BluetoothDevice device, String name)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Method m = device.getClass().getMethod("setAlias", String.class);
m.invoke(device, name);
}
I don't think you can rename the name of the paired device. You can only change the name from the paired device's settings.
Think of it like a wifi router, you cannot change the name of the router, but you can only connect to it.
However if you want,you could assign this way
Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
if (devices.size() > 0) {
for(int i=0;i<device.size();i++) {
mDevice[i] = device;
bondedDevices.add(mDevice.getName());
}
}
That way you could get the name of the paired Devices as a mDevice array. Hope it solved your issue

rfcomm bluetooth on google glass

I am having an Android-App [1] which I partly want to port to google-glass - this app uses bluetooth rfcomm. Now I am facing the following problem: when I use my connection code I see a pairing dialog on glass - showing me a large number and asks for a tap to confirm. But this is strange - as I usually have to enter my 4 digit pin on the phone - also I am getting auth problems ( smells like it is caused by not letting me enter the PIN )
Anyone using bluetooth-rfcomm on google-glass?
[1] https://github.com/ligi/DUBwise
I was having the exact problem like this! In this post I put my complete solution to this problem.
But basically the pairing is done like this:
In the BroadcastReceiver
if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){
BluetoothDevice device = ListDev.get(selectedDevice);
byte[] pinBytes = getStrFromName(device.getName(),7,11).getBytes(); // My devices had their own pin in their name, you can put a constant pin here or ask for one...
try {
Method m = device.getClass().getMethod("setPin", byte[].class);
m.invoke(device, pinBytes);
try {
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
So the pin is set automatically in this example, but you can always ask for a pin to the user.
Hope it helps!

listenUsingRfcommWithServiceRecord (String name, UUID uuid) Not working

So im trying to get this little piece of code to run
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Server", MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
But when i continue from the line where tmp should be assigned it is still null. Bluetooth is activated and everything but it simply wont set tmp to anything when i get to it. Any ideas why not? And btw. does this method not work on a 2.2 android machine since it crashes at that line on my 2.2 machine but not on my 4.1.2 device.
If any more information is needed to be able to answer please just ask for it and ill give it to the best of my ability.
Found out i hadn't given permission to the app to use bluetooth so solved.
I am completely new to Android development and ran into the same problem. Here is more help if other people run into this:
Because this is happening on the server side, be sure discoverability is enabled before starting the accept-connection thread. This can by starting the thread in the onActivityResult() method when the proper resultCode is received.

Android Bluetooth - source code

I have been strugling with a Bluetooth project on Android for weeks. Does anyone know where I can go to see the actual code that's used by Google to make their Bluetooth pairing and connection logic work?
I have been through all the documentaiton, the BluetoothChat application (which doesn't work as advertised ... tried it on 3 different handsets), as well as a bunch of other sites on the net, but still no luck. I need to get an app up and running on 2.1 or higher.
Any advice or help is greatly appreciated.
Yes the Bluetooth project didn't work for me also because the code for socket connection is not working
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
}
this is not working ...
replace this by the following code
BluetoothDevice hxm = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress());
Method m;
m = hxm.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
socket = (BluetoothSocket)m.invoke(hxm, Integer.valueOf(1));
Ah, if you're having issues with application level code I'm not sure staring at the Bluetooth manager source will be much help, but here you go: https://android.googlesource.com/platform/packages/apps/Bluetooth the Bluetooth manager app code.
I'll re-iterate it: this is honestly probably not going to be helpful for what you want. You should be able to get a reasonably working Bluetooth app without having to look at this.
EDIT: if you want the code that implements the Bluetooth packages (android.bluetooth), see https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth for that.
You can browse all the android.bluetooth package around here:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/bluetooth/BluetoothClass.java#BluetoothClass

Categories

Resources