Android wiimote套接字无法连接
我正在尝试将wiimote连接到我的OUYA(运行Android 4.1.2)。我已经设法让wiimotes使用其他应用程序进行连接,例如,所以我知道这是可能的,但我希望自己能够做到这一点 这就是我到目前为止所做的:Android wiimote套接字无法连接,android,bluetooth,wiimote,ouya,Android,Bluetooth,Wiimote,Ouya,我正在尝试将wiimote连接到我的OUYA(运行Android 4.1.2)。我已经设法让wiimotes使用其他应用程序进行连接,例如,所以我知道这是可能的,但我希望自己能够做到这一点 这就是我到目前为止所做的: private void bloothoothConnect(final BluetoothAdapter mBluetoothAdapter){ // Register the BroadcastReceiver IntentFilter filter = ne
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;
}
}
private void bloothoothConnect(最终蓝牙适配器MBluethoothAdapter){
//注册广播接收器
IntentFilter筛选器=新的IntentFilter(BluetoothDevice.ACTION\u已找到);
filter.addAction(BluetoothAdapter.ACTION\u DISCOVERY\u已启动);
filter.addAction(BluetoothAdapter.ACTION\u DISCOVERY\u FINISHED);
registerReceiver(新广播接收器(){
公共void onReceive(上下文、意图){
String action=intent.getAction();
//当发现发现发现设备时
if(BluetoothDevice.ACTION_FOUND.equals(ACTION)){
//从Intent获取BluetoothDevice对象
BluetoothDevice=intent.getParcelableExtra(BluetoothDevice.EXTRA\u设备);
如果(iSwiMote(设备)){
mBluetoothAdapter.cancelDiscovery();
连接远程(设备);
}
}
}
},过滤器);
mBluetoothAdapter.startDiscovery();
}
专用布尔值iSwimote(蓝牙设备){
String name=device.getName();
返回名称。equalsIgnoreCase(“任天堂RVL-CNT-01”);
}
专用void connectWiiMote(最终蓝牙设备){
最终时间间隔=30;
WiimoteRunnable nWiiMote=新的WiimoteRunnable(设备,时间间隔){
@凌驾
受保护的void onButtonDown(){//TODO
}};
线程n读取=新线程(nWiiMote);
nThread.start();
}
私有抽象类WiimoteRunnable实现Runnable{
私人蓝牙插座;
私人长间隔;
专用字节[]缓冲区=新字节[1024];
WiimoteRunnable(蓝牙设备,长时间间隔){
套接字=createL2CAPBluetoothSocket(设备);
this.tickInterval=tickInterval;
}
@SuppressLint(“新API”)
@凌驾
公开募捐{
试一试{
如果(!socket.isConnected()){
//这里有个街区!
socket.connect();
}
InputStream iStream=socket.getInputStream();
while(socket.isConnected()){
iStream.read(缓冲区);
//在这里使用字节缓冲区
睡眠(滴答声间隔);
}
}捕获(IOE2异常){
closeSocket();
}捕捉(中断异常e){
closeSocket();
返回;
}
}
私有void closeSocket(){
试一试{
socket.close();
}捕获(IOE异常){
返回;
}
}
//待以后实施
受保护的抽象void onButtonDown();
}
//看https://stackoverflow.com/questions/14761570/connecting-to-a-bluetooth-hid-device-mouse-using-l2cap
私有静态最终int类型_L2CAP=3;
/**
*使用L2CAP协议创建BluetoothSocket
*适用于HID蓝牙设备
*@param蓝牙设备
*@return-BluetoothSocket
*/
@SuppressLint(“新API”)
专用静态BluetoothSocket createL2CAPBluetoothSocket(蓝牙设备){
int type=type_L2CAP;//L2CAP协议
int fd=-1;//创建一个新套接字
boolean auth=false;//无身份验证
boolean encrypt=false;//未加密
int port=0;//要使用的端口(如果给定了UUID,则无效)
parcelouid[]uuid=device.getUuids();//蓝牙uuid服务
if(uuid==null){
如果(!device.fetchUUIDSWITHDP()){
返回null;
}否则{
uuid=device.getUuids();
}
}
试一试{
构造函数=BluetoothSocket.class.getDeclaredConstructor(
int.class,int.class,boolean.class,boolean.class,
BluetoothDevice.class、int.class、parceluid.class);
constructor.setAccessible(true);
BluetoothSocket客户端套接字=(BluetoothSocket)构造函数.newInstance(
类型、fd、身份验证、加密、设备、端口、uuid[0]);
返回clientSocket;
}捕获(例外e){
e、 printStackTrace();
返回null;
}
}
问题是当我到达socket.connect()
时,它会阻塞并且永远不会返回。套接字对象就在那里,在调试器中我可以看到它的所有数据
我按照获取套接字,而不是使用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();
}
}
private static final int CONTROL\u通道=0x11;
专用静态最终整数数据_通道=0x13;
私人蓝牙插座;
私有BluetoothSocket数据存储库;
私有输出流;
私有输入流是;
专用静态BluetoothSocket createL2CAPBluetoothSocket(BluetoothDevice设备,最终int通道){
int type=type_L2CAP;//L2CAP协议
int fd=-1;//创建一个新套接字
boolean auth=false;//无身份验证
boolean encrypt=false;//未加密
试一试{
构造函数=BluetoothSocket.class.getDeclaredConstructor(int.class,
int.class、boolean.class、boolean.class、BluetoothDevice.class、int.class、parceluid.class);
constructor.setAccessible(true);
BluetoothSocket客户端套接字=(BluetoothSocket)构造函数.newInstance(类型、fd、身份验证、加密、设备、,
通道,空);
返回clientSocket;
}捕获(例外e){
e、 printStackTrace();
返回null;
}
}
void connect(蓝牙设备){
试一试{
controlSo