首页 文章

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

提问于
浏览
10

Hey All

据我所知,Android的蓝牙堆栈(bluez)已在4.2上被取代 . 即使他们可能已经修复了许多以前的问题,但由于需要支持旧版本,我仍然需要与它们进行斗争 .

如果有人之前处理过这个问题并且可以解释一下,我会非常感激 .

问题#1 - 无法检测到损坏的通信(4.0和4.1 Android,Bluez蓝牙堆栈)

蓝牙应用程序连接到我们自己的 custom SPP device (我们使用标准 UUID ) . 它使用在其上运行的蓝牙服务's own process. It' s要求此应用程序运行蓝牙工作几个小时 .

power-save / screen lock 期间,应用程序保持 alive ,而数据通过 bluetooth radio 进入,我也定期检查设置的警报,我请求CPU时间重新连接并继续工作(如有必要)

现在;系统在大多数情况下工作正常,但是,在某些罕见的情况下 screenlocked 并且在 power-save 模式中,由于我不明白的原因, writing 进入 output-stream (蓝牙插座),一切似乎都没有通过检测到断开的连接 . 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):发送字节:[B @ 41e0bcf8 D / com.our.app.bluetooth(8711):要写入的蓝牙字节:[B @ 41e0bcf8 V / BluetoothSocket.cpp(8711) ):writeNative D / com.our.app.bluetooth(8711):写入蓝牙字节:[B @ 41e0bcf8

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

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

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

我注意到 SPP 设备正确配对,但有时,android设备会显示消息"Unable to pair to device X, incorrect PIN or Password" .

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

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

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

Thanks a million .

1 回答

  • 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;
    

相关问题