这个问题已经解决了!非常感谢布拉德、丹尼斯和瘾君子!你们是英雄!:)
这是工作代码。它连接到 Zeemote 并从中读取数据。
===== 代码 =====
公共类 ZeeTest 扩展 Activity {
@覆盖
公共无效 onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
设置内容视图(R.layout.main);
尝试 {
for (int i = 0; i < 3; i++) {
测试();
}
} 捕捉(异常 e){
e.printStackTrace();
}
}
私人布尔连接=假;
私有 BluetoothSocket 袜子;
私有输入流;
公共无效测试()抛出异常{
如果(连接){
返回;
}
BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter()。
getRemoteDevice("00:1C:4D:02:A6:55");
方法 m = zee.getClass().getMethod("createRfcommSocket",
新类[] { int.class });
袜子 = (BluetoothSocket)m.invoke(zee, Integer.valueOf(1));
Log.d("ZeeTest", "++++ 连接");
袜子.connect();
Log.d("ZeeTest", "++++ 已连接");
in = sock.getInputStream();
字节[]缓冲区=新字节[50];
int 读取 = 0;
Log.d("ZeeTest", "++++ 听力...");
尝试 {
而(真){
读= in.read(缓冲区);
连接=真;
StringBuilder buf = new StringBuilder();
for (int i = 0; i < 读取; i++) {
int b = 缓冲区[i] & 0xff;
如果(b < 0x10){
buf.append("0");
}
buf.append(Integer.toHexString(b)).append(" ");
}
Log.d("ZeeTest", "++++ Read "+ read +" bytes: "+ buf.toString());
}
} 捕捉(IOException e){}
Log.d("ZeeTest", "++++ Done: test()");
}
@覆盖
公共无效 onDestroy() {
尝试 {
如果(在!= null){
附寄();
}
如果(袜子!= null){
袜子.close();
}
} 捕捉(IOException e){
e.printStackTrace();
}
super.onDestroy();
}
}
=====原始问题=====
我正在尝试从运行 2.0.1 固件的 Moto Droid 连接到 Zeemote ( http://zeemote.com/ ) 游戏控制器。下面的测试应用程序确实连接到设备(LED 闪烁),但之后立即断开连接。
我在下面粘贴了两个测试应用程序:一个实际上尝试从输入流中读取,第二个只是坐在那里,等待设备在 5 秒后断开连接。是的,我确实有第三个版本 :) 它首先等待 ACL_CONNECTED 然后打开套接字,但它的行为没有什么新东西。
一些背景信息:我可以使用 bluez 工具(也附有日志)从我的笔记本电脑完美连接到 Zeemote。我确信 Droid也能够与 Zeemote 对话,因为来自 Market 的“Game Pro”可以正常工作(但它是一个驱动程序/服务,所以它可能使用较低级别的 API?)。
我注意到“adb bugreport”既没有报告 Zeemote 的 UUID 也没有报告 RFCOMM 频道,而它对所有其他设备(包括 Moto HS815 耳机,另一个“sdp browse”没有报告任何内容的哑设备)都报告了。此外,当设备启动时,Zeemote 的优先级为 0(其他的优先级为 100+)。
我在这里很茫然,我工作了很长时间,以至于我没有想法,所以非常感谢任何帮助(即使你不知道答案:))
谢谢,马克斯
测试申请号 1
此应用程序尝试从设备中实际读取。
===== 代码 =====
公共类 ZeeTest 扩展 Activity {
@覆盖
公共无效 onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
设置内容视图(R.layout.main);
尝试 {
测试();
} 捕捉(IOException e){
e.printStackTrace();
}
}
私有 BluetoothSocket 袜子;
私有输入流;
公共无效测试()抛出 IOException {
BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter()。
getRemoteDevice("00:1C:4D:02:A6:55");
袜子 = zee.createRfcommSocketToServiceRecord(
UUID.fromString("8e1f0cf7-508f-4875-b62c-fbb67fd34812"));
Log.d("ZeeTest", "++++ 连接");
袜子.connect();
Log.d("ZeeTest", "++++ 已连接");
in = sock.getInputStream();
字节[]缓冲区=新字节[1];
整数字节 = 0;
诠释 x = 0;
Log.d("ZeeTest", "++++ 听力...");
而(x < 2){
x++;
尝试 {
字节= in.read(缓冲区);
Log.d("ZeeTest", "++++ Read "+ bytes +" bytes");
} 捕捉(IOException e){
e.printStackTrace();
尝试 { Thread.sleep(100); } 捕捉(InterruptedException 即){}
}
}
Log.d("ZeeTest", "++++ Done: test()");
}
@覆盖
公共无效 onDestroy() {
尝试 {
如果(在!= null){
附寄();
}
如果(袜子!= null){
袜子.close();
}
} 捕捉(IOException e){
e.printStackTrace();
}
super.onDestroy();
}
}
===== 日志 =====
04-19 22:27:01.147:调试/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: 错误/BluetoothEventLoop.cpp(4029): event_filter: 收到信号 org.bluez.Device:PropertyChanged 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55 04-19 22:27:04.491:详细/BluetoothEventRedirector(7499):收到 android.bleutooth.device.action.UUID 04-19 22:27:04.905:调试/ZeeTest(8619):++++ 已连接 04-19 22:27:04.905: 调试/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:调试/ZeeTest(8619):++++ 完成:测试() 04-19 22:27:07.155:详细/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: 错误/BluetoothEventLoop.cpp(4029): event_filter: 收到信号 org.bluez.Device:PropertyChanged 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55
测试申请号 2
此测试连接并等待——对于显示自动断开问题很有用。
===== 代码 =====
公共类 ZeeTest 扩展 Activity {
@覆盖
公共无效 onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
设置内容视图(R.layout.main);
getApplicationContext().registerReceiver(接收者,
新的 IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
getApplicationContext().registerReceiver(接收者,
新 IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
尝试 {
BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter()。
getRemoteDevice("00:1C:4D:02:A6:55");
袜子 = zee.createRfcommSocketToServiceRecord(
UUID.fromString("8e1f0cf7-508f-4875-b62c-fbb67fd34812"));
Log.d("ZeeTest", "++++ 连接");
袜子.connect();
Log.d("ZeeTest", "++++ 已连接");
} 捕捉(IOException e){
e.printStackTrace();
}
}
私有静态最终 LogBroadcastReceiver 接收器 = new LogBroadcastReceiver();
公共静态类 LogBroadcastReceiver 扩展 BroadcastReceiver {
@覆盖
公共无效 onReceive(上下文上下文,意图意图){
Log.d("ZeeReceiver", intent.toString());
捆绑附加服务 = intent.getExtras();
for (String k : extras.keySet()) {
Log.d("ZeeReceiver", " Extra: "+ extras.get(k).toString());
}
}
}
私有 BluetoothSocket 袜子;
@覆盖
公共无效 onDestroy() {
getApplicationContext().unregisterReceiver(receiver);
如果(袜子!= null){
尝试 {
袜子.close();
} 捕捉(IOException e){
e.printStackTrace();
}
}
super.onDestroy();
}
}
===== 日志 =====
04-19 22:06:34.944: 调试/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(): call select(...)
04-19 22:06:38.217: 错误/BluetoothEventLoop.cpp(4029): event_filter: 收到信号 org.bluez.Device:PropertyChanged 从 /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55
04-19 22:06:38.428: VERBOSE/BluetoothEventRedirector(7499): 收到 android.bleutooth.device.action.UUID
04-19 22:06:38.968: 调试/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:调试/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:详细/BluetoothEventRedirector(7499):收到 android.bleutooth.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(): call select(...)
04-19 22:06:43.069: 错误/BluetoothEventLoop.cpp(4029): event_filter: 收到信号 org.bluez.Device:PropertyChanged from /org/bluez/4121/hci0/dev_00_1C_4D_02_A6_55
04-19 22:06:43.124: DEBUG/ZeeReceiver(7986): Intent { act=android.bluetooth.device.action.ACL_DISCONNECTED (有额外) }
04-19 22:06:43.124:调试/ZeeReceiver(7986):额外:00:1C:4D:02:A6:55
系统日志
===== 终端日志 =====
$ sdptool 浏览
查询 ...
浏览 00:1C:4D:02:A6:55 ...
$ sdptool 记录 00:1C:4D:02:A6:55
服务名称:Zeemote
服务记录句柄:0x10015
服务类 ID 列表:
UUID 128:8e1f0cf7-508f-4875-b62c-fbb67fd34812
协议描述符列表:
“L2CAP”(0x0100)
"RFCOMM" (0x0003)
频道:1
语言库属性列表:
代码_ISO639:0x656e
编码:0x6a
base_offset: 0x100
$ rfcomm 连接 /dev/tty10 00:1C:4D:02:A6:55
将 /dev/rfcomm0 连接到通道 1 上的 00:1C:4D:02:A6:55
按 CTRL-C 挂断
# rfcomm 显示 /dev/tty10
rfcomm0: 00:1F:3A:E4:C8:40 -> 00:1C:4D:02:A6:55 通道 1 已连接 [reuse-dlc release-on-hup tty-attached]
# 猫 /dev/tty10
(这里没有什么)
#hcidump
HCI 嗅探器 - 蓝牙数据包分析器 1.42 版
设备:hci0 snap_len:1028 过滤器:0xffffffff
< HCI 命令:创建连接 (0x01|0x0005) plen 13
> HCI 事件:命令状态 (0x0f) plen 4
> HCI 事件:连接完成 (0x03) plen 11
< HCI 命令:读取远程支持的功能 (0x01|0x001b) plen 2
> HCI 事件:读取远程支持的功能 (0x0b) plen 11
< ACL 数据:句柄 11 标志 0x02 dlen 10
L2CAP(s):信息请求:类型 2
> HCI 事件:命令状态 (0x0f) plen 4
> HCI 事件:页面扫描重复模式更改 (0x20) plen 7
> HCI 事件:最大插槽更改 (0x1b) plen 3
< HCI 命令:远程名称请求 (0x01|0x0019) plen 10
> HCI 事件:命令状态 (0x0f) plen 4
> ACL 数据:句柄 11 标志 0x02 dlen 16
L2CAP(s):信息 rsp:类型 2 结果 0
扩展功能掩码 0x0000
< ACL 数据:句柄 11 标志 0x02 dlen 12
L2CAP(s):连接请求:psm 3 scid 0x0040
> HCI 事件:已完成数据包数 (0x13) plen 5
> ACL 数据:句柄 11 标志 0x02 dlen 16
L2CAP(s):连接 rsp:dcid 0x04fb scid 0x0040 结果 1 状态 2
连接挂起 - 授权挂起
> HCI 事件:远程名称请求完成 (0x07) plen 255
> ACL 数据:句柄 11 标志 0x02 dlen 16
L2CAP(s):连接 rsp:dcid 0x04fb scid 0x0040 结果 0 状态 0
连接成功
< ACL 数据:句柄 11 标志 0x02 dlen 16
L2CAP(s):配置请求:dcid 0x04fb 标志 0x00 clen 4
MTU 1013
(使用 bluez 正确接收事件)
===== adb bugreport 的一部分 =====
--已知设备--
00:19:A1:2D:16:EA 绑定 (0) LG U830
00001105-0000-1000-8000-00805f9b34fb RFCOMM 频道 = 17
00:1C:4D:02:A6:55 绑定 (0) Zeemote JS1
00:0B:2E:6E:6F:00 绑定 (0) 摩托罗拉 HS815
00001108-0000-1000-8000-00805f9b34fb RFCOMM 频道 = 1
0000111e-0000-1000-8000-00805f9b34fb RFCOMM 通道 = 2
00:1F:3A:E4:C8:40 绑定 (0) BRCM BT4X
00001105-0000-1000-8000-00805f9b34fb RFCOMM 频道 = 9
00:18:42:EC:E2:99 绑定 (0) N95
00001105-0000-1000-8000-00805f9b34fb RFCOMM 频道 = 9
===== 启动日志摘录 =====
04-18 21:55:10.382:VERBOSE/BluetoothEventRedirector(1985):收到 android.bluetooth.adapter.action.STATE_CHANGED 04-18 21:55:10.421: 调试/BT HSHFP(1237): 加载优先级 00:19:A1:2D:16:EA = 100 04-18 21:55:10.428: 调试/BT HSHFP(1237): 加载优先级 00:1C:4D:02:A6:55 = 0 04-18 21:55:10.444: 调试/BT HSHFP(1237): 加载优先级 00:0B:2E:6E:6F:00 = 101 04-18 21:55:10.749: 调试/BT HSHFP(1237): 加载优先级 00:1F:3A:E4:C8:40 = 100 04-18 21:55:10.780: 调试/BT HSHFP(1237): 加载优先级 00:18:42:EC:E2:99 = 100