可能类似于未答复的帖子here,但我们有一个Android应用程序(在多个手机和多个Android 2.1+版本上测试),需要监听并接受来自远程蓝牙设备的连接。远程设备是一个数字笔,但重点是笔与手机配对,然后通过SPP发送数据,SPP使用OBEX,使用RFComm所以这一切都应该没问题。
目前,该应用程序的工作原理是允许Android设备接收OBEX有效负载,然后让应用程序查看蓝牙文件夹以获取有效负载,但我们希望应用程序能够直接与远程设备通信。 请记住远程连接到Android手机,手机无法连接到笔。
我们的测试代码基于Android示例中提供的示例BluetoothChat应用程序,但基本上adapter.listenUsingRfcommWithServiceRecord
永远不会被调用,我们在 Motorola Defy + DDMS日志中看到的最佳效果是:
INFO/BtOppRfcommListener(2577): Accepted connectoin from 00:07:CF:55:94:FB
INFO/BtOpp Service(2577): Start Obex Server
DEBUG/Obex ServerSession(2577): java.io.IOException: Software caused connection abort
这似乎表明Android已接受该连接,但该应用程序无法使用该连接。使用的UUID与同一应用程序的JME版本中使用的UUID相同,由笔供应商提供。
答案 0 :(得分:1)
Android开发人员在复制BluetoothChat应用程序代码时最常犯的错误是我们不遵循该应用程序的流程。
实现此代码时的常见错误,如“服务发现失败”,“软件导致连接中止”,“连接中止连接”,“无法启动服务发现”,“连接丢失”等因素忽略了流动。
我在我的应用程序中实现BluetoothChat代码时遇到了所有这些问题,解决方案是纠正流程。
例如在我的情况下:
OnCreate:
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
OnStart:
if(this.mChatService == null)
this.mChatService = new BluetoothChatService(this, mHandler);
OnResume:
if ((mChatService != null) && (mBluetoothAdapter.isEnabled())) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
OnDestroy:
if(mTransferService != null) mTransferService.stop();
onActivityResult:
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
if(mChatService .getState() != BluetoothChatService.STATE_CONNECTED){
String address = data.getExtras().getString(ViewContactList.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device);
}
else{
if(messageString.length() > 0)
MyCurrentActivity.this.sendMessage(messageString);
}
简单来说,在你调用之前,以两种设备都处于mState = STATE_LISTEN的方式实现代码
mChatService.connect(device);
答案 1 :(得分:1)
在我们的案例中,我们发现唯一能够可靠地接受来自远程设备的蓝牙OPP数据的解决方案是使用“隐藏的”Android API。如果您检查Android源代码,则会定义其他注释@hide
的方法,这些方法会从导出的Android jar和API文档中排除它们。
如果可能,应避免使用这些方法,并且不保证在Android版本中保持一致。
有两种方法可以在代码中包含这些内容:
我们选择了#1,因为我们的要求很少。
Class<?>[] args = new Class[] { int.class };
Method listenMethod = BluetoothAdapter.class.getMethod(listenMethod, args);
方法名称是(按优先顺序排列)listenUsingEncryptedRfcommOn
,listenUsingRfcommOn
或listenUsingUnencrytptedRfcommOn
BluetoothAdapter target = *your adapter, probably the default one*;
BluetoothServerSocket sock = (BluetoothServerSocket) (listenMethod.invoke(target, new Object[] { channel }));
在我们的情况下,OPP频道 12
如果您设法获得BluetoothServerSocket
返回(省略例外处理,您的里程可能会有所不同,建议用户自行决定,不提供保证等等),您应该能够使用它来收听传入的OPP数据。