OUYA (Android 4.1.2 を実行) に wiimote を接続しようとしています。Bluez-IMEなどの他のアプリを使用してwiimoteを接続することができたので、それが可能であることは知っていますが、自分でできるようにしたいです
これは私がこれまでに持っているものです:
private void bloothoothConnect(final BluetoothAdapter mBluetoothAdapter){
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(isWiiMote(device)){
mBluetoothAdapter.cancelDiscovery();
connectWiiMote(device);
}
}
}
}, filter);
mBluetoothAdapter.startDiscovery();
}
private boolean isWiiMote(BluetoothDevice device){
String name = device.getName();
return name.equalsIgnoreCase("Nintendo RVL-CNT-01");
}
private void connectWiiMote(final BluetoothDevice device){
final int tickInterval = 30;
WiimoteRunnable nWiiMote = new WiimoteRunnable(device, tickInterval){
@Override
protected void onButtonDown() { // TODO
}};
Thread nThread = new Thread(nWiiMote);
nThread.start();
}
private abstract class WiimoteRunnable implements Runnable{
private BluetoothSocket socket;
private long tickInterval;
private byte[] buffer = new byte[1024];
WiimoteRunnable(BluetoothDevice device, long tickInterval) {
socket = createL2CAPBluetoothSocket(device);
this.tickInterval = tickInterval;
}
@SuppressLint("NewApi")
@Override
public void run() {
try {
if(!socket.isConnected()){
// blocks here!
socket.connect();
}
InputStream iStream = socket.getInputStream();
while(socket.isConnected()){
iStream.read(buffer);
// do stuff with byte buffer here
Thread.sleep(tickInterval);
}
} catch (IOException e2) {
closeSocket();
} catch (InterruptedException e) {
closeSocket();
return;
}
}
private void closeSocket(){
try {
socket.close();
} catch (IOException e) {
return;
}
}
// to be implemented later
protected abstract void onButtonDown();
}
// see https://stackoverflow.com/questions/14761570/connecting-to-a-bluetooth-hid-device-mouse-using-l2cap
private static final int TYPE_L2CAP = 3;
/**
* Create a BluetoothSocket using L2CAP protocol
* Useful for HID Bluetooth devices
* @param BluetoothDevice
* @return BluetoothSocket
*/
@SuppressLint("NewApi")
private static BluetoothSocket createL2CAPBluetoothSocket(BluetoothDevice device){
int type = TYPE_L2CAP; // L2CAP protocol
int fd = -1; // Create a new socket
boolean auth = false; // No authentication
boolean encrypt = false; // Not encrypted
int port = 0; // port to use (useless if UUID is given)
ParcelUuid[] uuid = device.getUuids(); // Bluetooth UUID service
if(uuid==null){
if(!device.fetchUuidsWithSdp()){
return null;
} else {
uuid = device.getUuids();
}
}
try {
Constructor<BluetoothSocket> constructor = BluetoothSocket.class.getDeclaredConstructor(
int.class, int.class, boolean.class, boolean.class,
BluetoothDevice.class, int.class, ParcelUuid.class);
constructor.setAccessible(true);
BluetoothSocket clientSocket = (BluetoothSocket) constructor.newInstance(
type, fd, auth, encrypt, device, port, uuid[0]);
return clientSocket;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
問題は、socket.connect()
ブロックされて戻ってこないときです。ソケット オブジェクトがそこにあり、デバッガーでそのすべてのデータを確認できます。
L2CAPを使用してBluetooth HIDデバイス(マウス)に接続するに従ってソケットを取得しています