这个问题已经解决了!非常感谢Brad、Denis和junkie!你们是英雄!:)
下面是工作代码。它连接到Zeemote并从中读取数据。
===== 代码 =====
public class ZeeTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { for (int i = 0; i < 3; i++) { test(); } } catch (Exception e) { e.printStackTrace(); } }
private boolean connected = false; private BluetoothSocket sock; private InputStream in; public void test() throws Exception { if (connected) { return; } BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter(). getRemoteDevice("00:1C:4D:02:A6:55"); Method m = zee.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); sock = (BluetoothSocket)m.invoke(zee, Integer.valueOf(1)); Log.d("ZeeTest", "++++ 连接中"); sock.connect(); Log.d("ZeeTest", "++++ 已连接"); in = sock.getInputStream(); byte[] buffer = new byte[50]; int read = 0; Log.d("ZeeTest", "++++ 监听..."); try { while (true) { read = in.read(buffer); connected = true; StringBuilder buf = new StringBuilder(); for (int i = 0; i < read; i++) { int b = buffer[i] & 0xff; if (b < 0x10) { buf.append("0"); } buf.append(Integer.toHexString(b)).append(" "); } Log.d("ZeeTest", "++++ 读取了 "+ read +" 字节: "+ buf.toString()); } } catch (IOException e) {} Log.d("ZeeTest", "++++ 完成:test()"); } @Override public void onDestroy() { try { if (in != null) { in.close(); } if (sock != null) { sock.close(); } } catch (IOException e) { e.printStackTrace(); } super.onDestroy(); } }
===== 原始问题 =====
我正在尝试从运行2.0.1固件的Moto Droid连接到Zeemote (http://zeemote.com/) 游戏控制器。下面贴出两个测试应用程序:一个实际上尝试从输入流中读取数据,另一个则只是坐在那里,等待设备在5秒后断开连接。是的,我有第三个版本 :),它首先等待ACL_CONNECTED,然后打开套接字,但行为没有任何变化。
一些背景信息: 使用bluez工具,我可以完美地从我的笔记本电脑连接到Zeemote(日志也附在此处)。我确信Droid也可以与Zeemote通信,因为市场上的“Game Pro”可以很好地与它配合使用(但它可能使用了较低级别的API驱动程序/服务)。
我注意到,“adb bugreport”对于所有其他设备(包括Moto HS815耳机和另一个哑设备,“sdp browse”报告为空)都会报告UUID和RFCOMM通道,但对于Zeemote则不会这样做。此外,当设备启动时,Zeemote的优先级为0(其他设备的优先级为100+)。
我非常困惑,已经努力调试了很长时间,现在没有更多的想法了,所以任何帮助都将不胜感激(即使您不知道答案 :))
谢谢, Max
测试应用程序1
此应用程序尝试实际从设备中读取内容。
===== 代码 =====
public class ZeeTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { test(); } catch (IOException e) { e.printStackTrace(); } }
private BluetoothSocket sock; private InputStream in; public void test() throws IOException { BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter(). getRemoteDevice("00:1C:4D:02:A6:55"); sock = zee.createRfcommSocketToServiceRecord( UUID.fromString("8e1f0cf7-508f-4875-b62c-fbb67fd34812")); Log.d("ZeeTest", "++++ 正在连接"); sock.connect(); Log.d("ZeeTest", "++++ 已连接"); in = sock.getInputStream(); byte[] buffer = new byte[1]; int bytes = 0; int x = 0; Log.d("ZeeTest", "++++ 正在监听..."); while (x < 2) { x++; try { bytes = in.read(buffer); Log.d("ZeeTest", "++++ 读取 "+ bytes +" 字节"); } catch (IOException e) { e.printStackTrace(); try { Thread.sleep(100); } catch (InterruptedException ie) {} } } Log.d("ZeeTest", "++++ 完成:test()"); } @Override public void onDestroy() { try { if (in != null) { in.close(); } if (sock != null) { sock.close(); } } catch (IOException e) { e.printStackTrace(); } super.onDestroy(); } }
===== 日志 =====
04-19 22:27:01.147: DEBUG/ZeeTest(8619): ++++ 正在连接 04-19 22:27:04.085: INFO/usbd(1062): process_usb_uevent_message(): buffer = add@/devices/virtual/bluetooth/hci0/hci0:1 04-19 22:27:04.085: INFO/usbd(1062): main(): call select(...) 04-19 22:27:04.327: ERROR/BluetoothEventLoop.cpp(4029): event_filter: 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55 接收到信号 org.bluez.Device:PropertyChanged 04-19 22:27:04.491: VERBOSE/BluetoothEventRedirector(7499): 接收到 android.bleutooth.device.action.UUID 04-19 22:27:04.905: DEBUG/ZeeTest(8619): ++++ 已连接 04-19 22:27:04.905: DEBUG/ZeeTest(8619): ++++ 正在监听... 04-19 22:27:05.538: WARN/System.err(8619): java.io.IOException: 软件引起的连接中止 04-19 22:27:05.600: WARN/System.err(8619): at android.bluetooth.BluetoothSocket.readNative(Native Method) ... 04-19 22:27:05.717: WARN/System.err(8619): java.io.IOException: 软件引起的连接中止 04-19 22:27:05.717: WARN/System.err(8619): at android.bluetooth.BluetoothSocket.readNative(Native Method) ... 04-19 22:27:05.819: DEBUG/ZeeTest(8619): ++++ 完成:test() 04-19 22:27:07.155: VERBOSE/BluetoothEventRedirector(7499): 接收到 android.bleutooth.device.action.UUID 04-19 22:27:09.077: INFO/usbd(1062): process_usb_uevent_message(): buffer = remove@/devices/virtual/bluetooth/hci0/hci0:1 04-19 22:27:09.085: INFO/usbd(1062): main(): call select(...) 04-19 22:27:09.139: ERROR/BluetoothEventLoop.cpp(4029): event_filter: 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55 接收到信号 org.bluez.Device:PropertyChanged
测试应用程序No. 2
这个测试连接并等待 -- 对于显示自动断开问题很有用。
===== 代码 =====
public class ZeeTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED)); getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED)); try { BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter(). getRemoteDevice("00:1C:4D:02:A6:55"); sock = zee.createRfcommSocketToServiceRecord( UUID.fromString("8e1f0cf7-508f-4875-b62c-fbb67fd34812"));
Log.d("ZeeTest", "++++ 正在连接"); sock.connect(); Log.d("ZeeTest", "++++ 连接成功"); } catch (IOException e) { e.printStackTrace(); } }
private static final LogBroadcastReceiver receiver = new LogBroadcastReceiver(); public static class LogBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("ZeeReceiver", intent.toString()); Bundle extras = intent.getExtras(); for (String k : extras.keySet()) { Log.d("ZeeReceiver", " 额外信息: "+ extras.get(k).toString()); } } }
private BluetoothSocket sock; @Override public void onDestroy() { getApplicationContext().unregisterReceiver(receiver); if (sock != null) { try { sock.close(); } catch (IOException e) { e.printStackTrace(); } } super.onDestroy(); } }
===== 日志 =====
04-19 22:06:34.944: DEBUG/ZeeTest(7986): ++++ 正在连接 04-19 22:06:38.202: INFO/usbd(1062): process_usb_uevent_message(): buffer = add@/devices/virtual/bluetooth/hci0/hci0:1 04-19 22:06:38.202: INFO/usbd(1062): main(): 调用 select(...) 04-19 22:06:38.217: ERROR/BluetoothEventLoop.cpp(4029): event_filter: 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55 接收到信号 org.bluez.Device:PropertyChanged 04-19 22:06:38.428: VERBOSE/BluetoothEventRedirector(7499): 收到 android.bluetooth.device.action.UUID 04-19 22:06:38.968: DEBUG/ZeeTest(7986): ++++ 连接成功 04-19 22:06:39.061: DEBUG/ZeeReceiver(7986): Intent { act=android.bluetooth.device.action.ACL_CONNECTED (有额外信息) } 04-19 22:06:39.108: DEBUG/ZeeReceiver(7986): 额外信息: 00:1C:4D:02:A6:55 04-19 22:06:39.538: INFO/ActivityManager(4029): 显示 zee.test/.ZeeTest 的活动:5178 毫秒(总共 5178 毫秒) 04-19 22:06:41.014: VERBOSE/BluetoothEventRedirector(7499): 收到 android.bluetooth.device.action.UUID 04-19 22:06:43.038: INFO/usbd(1062): process_usb_uevent_message(): buffer = remove@/devices/virtual/bluetooth/hci0/hci0:1 04-19 22:06:43.038: INFO/usbd(1062): main(): 调用 select(...) 04-19 22:06:43.069: ERROR/BluetoothEventLoop.cpp(4029): event_filter: 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55 接收到信号 org.bluez.Device:PropertyChanged 04-19 22:06:43.124: DEBUG/ZeeReceiver(7986): Intent { act=android.bluetooth.device.action.ACL_DISCONNECTED (有额外信息) } 04-19 22:06:43.124: DEBUG/ZeeReceiver(7986): 额外信息: 00:1C:4D:02:A6:55