Mringwal's answer is correct, besides the NDK approach, you can use reflection on some devices to achieve L2CAP connectivity:
public static BluetoothSocket createL2CAPBluetoothSocket(String address, int psm){ return createBluetoothSocket(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){ 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) { return null; } }
where TYPE_L2CAP is an integer having a constant value of 3.
Please note that this approach will only work on some Android devices.
Writing a HID application is not an easy task. You need to implement a report descriptor parser, a component used to โdiscoverโ the capabilities (special keys, functions) of a remote HID device. You will also need to study the HID protocol and workflow, a copy is available here: http://www.dawidurbanski.pl/public/download/projekty/bluepad/HID_SPEC_V10.pdf
There are already professional programs that do just that, supporting HID on Android, for example, this software: http://teksoftco.com/index.php?section=product&pid=24
Due to stack limitations, the L2CAP protocol is not available on all devices, so a solution that works on ALL devices is currently not possible.