2013-06-02 245 views
3

我试图将wiimote连接到我的OUYA(运行Android 4.1.2)。我已经成功地得到的wiimote使用像Bluez-IME其他应用程序连接起来,所以我知道这是可能的,但我希望能够做我自己Android 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()它阻止并从不返回。套接字对象在那里,在调试器中,我可以看到它的所有数据。

我得到的插座,每Connecting to a bluetooth HID device (mouse) using L2CAP

回答

2

而不是使用你需要使用(在你的代码或端口号)的频道号码的L2CAP插座的UUID。要连接到wiimote,您需要分别打开套接字来控制(从您的应用程序到wiimote的命令)和数据(从您的应用程序输入wiimote)频道。

private static final int CONTROL_CHANNEL = 0x11; 
private static final int DATA_CHANNEL = 0x13; 

private BluetoothSocket controlSocket; 
private BluetoothSocket dataSocket; 

private OutputStream os; 
private InputStream is; 

private static BluetoothSocket createL2CAPBluetoothSocket(BluetoothDevice device, final int channel) { 
    int type = TYPE_L2CAP; // L2CAP protocol 
    int fd = -1; // Create a new socket 
    boolean auth = false; // No authentication 
    boolean encrypt = false; // Not encrypted 

    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, 
       channel, null); 
     return clientSocket; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

void connect(BluetoothDevice device) { 
    try { 
     controlSocket = createL2CAPBluetoothSocket(device, CONTROL_CHANNEL);   
     controlSocket.connect(); 
     os = controlSocket.getOutputStream(); 

     dataSocket = createL2CAPBluetoothSocket(device, DATA_CHANNEL); 
     dataSocket.connect(); 
     is = dataSocket.getInputStream();  

     // open transmit & receive threads for input and output streams appropriately 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+0

谢谢!完美按钮按下!试图获得加速度计数据以及la:http://wiibrew.org/wiki/Wiimote –

+0

有谁知道如果l2cap回声请求(如l2ping如何工作)在Android中支持和如何?这个示例代码期望一个频道,但我相信回声请求将没有频道。感谢帮助! –