I am able to pair a bluetooth keyboard but not able to connect so as to make it an input device. I went through the documentation provided at developer site - http://developer.android.com/guide/topics/connectivity/bluetooth.html#Profiles
It says that the Android Bluetooth API provides implementations for the following Bluetooth profiles but you can implement the interface BluetoothProfile to write your own classes to support a particular Bluetooth profile.
There is no documentation how to implement BluetoothProfile for HID bluetooth device(Keyboard)
Android has itself implemented bluetooth connection for HID devices but those API's are hidden. I tried reflection to use them too. I do not get any error but keyboard does not get connected as input device. This is what i have done -
private void connect(final BluetoothDevice bluetoothDevice) {
if(bluetoothDevice.getBluetoothClass().getDeviceClass() == 1344){
final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.i("btclass", profile + "");
if (profile == getInputDeviceHiddenConstant()) {
Class instance = null;
try {
//instance = Class.forName("android.bluetooth.IBluetoothInputDevice");
instance = Class.forName("android.bluetooth.BluetoothInputDevice");
Method connect = instance.getDeclaredMethod("connect", BluetoothDevice.class);
Object value = connect.invoke(proxy, bluetoothDevice);
Log.e("btclass", value.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(int profile) {
}
};
mBluetoothAdapter.getProfileProxy(this, mProfileListener,getInputDeviceHiddenConstant());
}
}
public static int getInputDeviceHiddenConstant() {
Class<BluetoothProfile> clazz = BluetoothProfile.class;
for (Field f : clazz.getFields()) {
int mod = f.getModifiers();
if (Modifier.isStatic(mod) && Modifier.isPublic(mod) && Modifier.isFinal(mod)) {
try {
if (f.getName().equals("INPUT_DEVICE")) {
return f.getInt(null);
}
} catch (Exception e) {
Log.e("", e.toString(), e);
}
}
}
return -1;
}
Bluetooth Keyboard to Android – PairingYou can pair a bluetooth keyboard easily, as you pair any bluetooth device. First, go to Settings and enable Bluetooth in your device. Then, your phone or tablet will detect the available Bluetooth keyboard and pairing will be done almost automatically.
HID (Human Interface Device) is the USB protocol that is used by a conventional keyboard and mouse. HID proxy mode allows a Bluetooth keyboard and mouse to function without loading the Bluetooth HCI driver. With HID proxy mode, the computer believes it is interacting with a conventional keyboard or mouse.
The head tracker human interface device (HID) protocol, available for devices running Android 13 and higher, allows for a head-tracking device to be connected to an Android device through USB or Bluetooth and be exposed to the Android framework and apps through the sensors framework.
Due to security reasons, it is not possible for third party applications to connect to a bluetooth keyboard as the application can be a keylogger. So it can be only done manually by the user.
Here is the code I used on Android Marshmallow (6.0).. To get an L2CAP connection started (Needed for HID)
public static BluetoothSocket createL2CAPBluetoothSocket(String address, int psm){
return createBluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, false,false, address, psm);
}
// method for creating a bluetooth client socket
private static BluetoothSocket createBluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address, int port){
Log.e(TAG, "Creating socket with " + address + ":" + port);
try {
Constructor<BluetoothSocket> constructor = BluetoothSocket.class.getDeclaredConstructor(
int.class, int.class,boolean.class,boolean.class,String.class, int.class);
constructor.setAccessible(true);
BluetoothSocket clientSocket = (BluetoothSocket) constructor.newInstance(type,fd,auth,encrypt,address,port);
return clientSocket;
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Boolean connect(View v) {
try {
// TODO: Check bluetooth enabled
mDevice = getController();
if (mDevice != null) {
Log.e(TAG, "Controller is paired");
// Create socket
mSocket = createL2CAPBluetoothSocket(mDevice.getAddress(), 0x1124);
if (mSocket != null) {
if (!mSocket.isConnected()) {
mSocket.connect();
}
Log.e(TAG, "Socket successfully created");
ConnectedThread mConnectedThread = new ConnectedThread(mSocket);
mConnectedThread.run();
}
} else {
showToast("Controller is not connected");
}
return true;
} catch (Exception e) {
e.printStackTrace();
if (e instanceof IOException){
// handle this exception type
} else {
// We didn't expect this one. What could it be? Let's log it, and let it bubble up the hierarchy.
}
return false;
}
}
private BluetoothDevice getController() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("Wireless Controller")) // Change to match DS4 - node name
{
Log.d(TAG, "Found device named: " + device.getName());
return device;
}
}
}
return null;
}
It can still have problems creating the Service, and you need to set the correct L2CAP PSAM for the device, but hope it can help..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With