我明白Android的蓝牙堆栈(bluez)在4.2中被替换了.即使他们可能已经修复了很多以前的问题,由于需要支持旧版本,我仍然需要与他们战斗.
如果有人以前处理过这个问题,可能会有一些光明,我会非常感激.
问题#1 – 无法检测到破坏的通信(4.0和4.1 Android,Bluez蓝牙堆栈)
蓝牙应用程序连接到我们自己的自定义SPP设备(我们使用标准UUID).它使用运行在其自身进程上的蓝牙服务.这个应用程序需要运行几个小时才做蓝牙工作.
在省电/屏幕锁定期间,应用程序在数据通过蓝牙无线电进入时保持活动,并且我也会定期检查设置的警报,其中我要求cpu时间重新连接&继续工作(如有必要)
现在;系统大部分时间工作正常,但是在某些罕见的情况下,当屏幕锁定和省电模式时,由于我不明白的原因,写入输出流(蓝牙插座)时,一切似乎都是通过检测不到断开的连接.该spp设备仍然声明连接&配对是有效的,但没有收到.
在Android端,日志显示了一个本机调用BluetoothSocket.cpp :: writeNative(假设它与bluez蓝牙协议栈直接相关),这似乎正好将这些字节正确地写入蓝牙无线电,而不报告任何错误.
public void write(byte[] bytes) { try { Log.d(LOGGER.TAG_BLUETOOTH," bluetooth bytes to write : "+bytes); mmOutStream.write(bytes); mmOutStream.flush(); Log.d(LOGGER.TAG_BLUETOOTH," bluetooth bytes written : "+bytes); } catch (IOException e) { e.printStackTrace(); } }
logcat:
D/com.our.app.bluetooth( 8711): bytes sending : [B@41e0bcf8
D/com.our.app.bluetooth( 8711): bluetooth bytes to write :[B@41e0bcf8
V/BluetoothSocket.cpp( 8711): writeNative
D/com.our.app.bluetooth( 8711): bluetooth bytes written :[B@41e0bcf8
问题 – 假设在应用程序级别检查和心跳线之间,在这种情况下,在套接字I / O操作上应该检测到破坏的通信是正确的吗?或者可以在省电时蓝牙收音机是否下降?
问题#2 – 从配对列表突然下降.
在Android 4.0& 4.1,在某些情况下,设备从配对列表中无法解释.即使这是罕见的,有些只是在某些特定的设备…这是一种情况下,防止手机重新配对和连接容易.
我注意到SPP设备配对正确,但有时Android设备会显示“无法配对设备X,PIN或密码不正确”的消息.
注意:对于Android版本< 4.2我们使用不安全的通信(createInsecureRfcommSocket,由于此版本的其他android连接问题). 问题 – 会话期间刷新PIN /密码的频率如何? 这可能是我们的SPP设备中的一个错误,但是有一些不是什么想法的机会呢? 太感谢了.
解决方法
private boolean refreshDeviceCache(BluetoothGatt gatt){ try { BluetoothGatt localBluetoothGatt = gatt; Method localMethod = localBluetoothGatt.getClass().getMethod("refresh",new Class[0]); if (localMethod != null) { boolean bool = ((Boolean) localMethod.invoke(localBluetoothGatt,new Object[0])).booleanValue(); return bool; } } catch (Exception localException) { Log.e(TAG,"An exception occured while refreshing device"); } return false;} public boolean connect(final String address) { if (mBluetoothAdapter == null || address == null) { Log.w(TAG,"BluetoothAdapter not initialized or unspecified address."); return false; } // PrevIoUsly connected device. Try to reconnect. if (mBluetoothGatt != null) { Log.d(TAG,"Trying to use an existing mBluetoothGatt for connection."); if (mBluetoothGatt.connect()) { return true; } else { return false; } } final BluetoothDevice device = mBluetoothAdapter .getRemoteDevice(address); if (device == null) { Log.w(TAG,"Device not found. Unable to connect."); return false; } // We want to directly connect to the device,so we are setting the // autoConnect // parameter to false. mBluetoothGatt = device.connectGatt(MyApp.getContext(),false,mGattCallback)); refreshDeviceCache(mBluetoothGatt); Log.d(TAG,"Trying to create a new connection."); return true;