Android 4.0和4.1蓝牙问题.检测破碎的通信并丢弃配对

eha*_*noc 10 android bluetooth spp bluez android-bluetooth

嘿所有,

据我所知,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();
            }
        }
Run Code Online (Sandbox Code Playgroud)

logcat:

D/com.our.app.bluetooth(8711):发送字节:[B @ 41e0bcf8

D/com.our.app.bluetooth(8711):要写的蓝牙字节:[B @ 41e0bcf8

V/BluetoothSocket.cpp(8711):writeNative

D/com.our.app.bluetooth(8711):写入蓝牙字节:[B @ 41e0bcf8

问题 - 假设除了应用程序级别检查和心跳之外,应该在套接字I/O操作(如本例中)检测到损坏的通信是否正确?或者蓝牙收音机在省电期间是否会停机?

问题#2 - 配对列表突然下降.

在Android 4.0和4.1中,在某些情况下,设备无法从配对列表中删除.即使这种情况很少见,有些只在某些特定的设备上......这是一种可以防止手机重新配对和连接的情况.

我注意到SPP设备正确配对,但有时,Android设备会显示消息"无法与设备X配对,PIN或密码不正确".

注意:对于Android版本<4.2,我们使用不安全的通信(createInsecureRfcommSocket,因为此版本的其他Android连接问题).

问题 - 在会话期间刷新此PIN /密码的频率如何?

这很可能是我们的SPP设备中的一个错误,但是如果不是这样的概率,那么任何想法?

万分感谢.

小智 1

这是在 Nexus 7 上运行 android 4.4.2

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;
Run Code Online (Sandbox Code Playgroud)