489次成功连接后,android蓝牙连接失败

use*_*364 9 java android bluetooth spp

不幸的是,我的android蓝牙有一些问题.对于我的测试环境,我使用的是带有Android 4.4.2的Nexus 4.

我的PC上有一个Java应用程序,它使用bluecove作为客户端进行SPP连接.该程序正在寻找一个特殊的服务名称,并与我的Android手机连接.然后它发送72个字节到我的Android手机,并等待答案.得到答案时,程序会睡3秒钟而不是重新开始.

在我的Android手机上,我有一个带有后台蓝牙监听器的应用程序,它在启动时启动.此应用程序基于BluetoothChat示例演示.当接收蓝牙数据时,我检查传入的数据并发回答案.

一切正常.但是在489蓝牙连接之后,Android应用程序在PC-java-app正在进行时失败并显示以下错误代码:

getBluetoothService() called with no BluetoothManagerCallback
Shutting down VM
threadid=1: thread exiting with uncaught exception (group=0x41b34ba8)
FATAL EXCEPTION: main
Process: de.tum.lme.diamantum:remote_blue, PID: 21567
java.lang.NullPointerException: FileDescriptor must not be null
    at android.os.ParcelFileDescriptor.<init>(ParcelFileDescriptor.java:174)
    at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:905)
    at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:897)
    at android.bluetooth.IBluetooth$Stub$Proxy.createSocketChannel(IBluetooth.java:1355)
    at android.bluetooth.BluetoothSocket.bindListen(BluetoothSocket.java:349)
    at android.bluetooth.BluetoothAdapter.createNewRfcommSocketAndRecord(BluetoothAdapter.java:1055)
    at android.bluetooth.BluetoothAdapter.listenUsingRfcommWithServiceRecord(BluetoothAdapter.java:976)
    at com.test.btconn.BluetoothHandling$AcceptThread.<init>(BluetoothHandling.java:449)
    at com.test.btconn.BluetoothHandling.start(BluetoothHandling.java:216)
    at com.test.btconn.BluetoothListenerService.setupBtSockets(BluetoothListenerService.java:330)
    at com.test.btconn.BluetoothListenerService.manageBtState(BluetoothListenerService.java:249)
    at com.test.btconn.BluetoothListenerService.setBtStateDisconnected(BluetoothListenerService.java:383)
    at com.test.btconn.BluetoothListenerService.access$5(BluetoothListenerService.java:378)
    at com.test.btconn.BluetoothListenerService$2.handleMessage(BluetoothListenerService.java:421)
Run Code Online (Sandbox Code Playgroud)

因此,应用程序的ParcelFileDescriptor存在问题,该问题突然变为空.但为什么?

当改变PC-java-app上的暂停时间时,使用各种数据大小来传输和使用不同的智能手机时,也会发生上述所有情况.当使用反射"listenUsingRfcommWithServiceRecord"时,505传输后也会发生相同的情况.使用唤醒锁也没有任何改变.

顺便说一下,使用BluetoothChat样本时我也有同样的行为.

所以,有人提示,会发生什么?

更新:

如果蓝牙状态为3,则每次连接后BluetoothServerSocket都会关闭,BluetoothSocket会关闭.

Daw*_*per 14

问题似乎与您设备上的文件描述符限制有关.没有为这个问题的报告在这里

在创建蓝牙套接字期间,新的fd是 从系统获取的两个新FD.您似乎没有正确关闭以前的BT连接,因此在您达到限制之前,已使用的FD数量会稳步增加.

为避免这种情况,您至少必须在完成操作后调用从通话中收到close()BluetoothServerSocketlistenUsingRfcommWithServiceRecord().您还应该检查是否要保留连接到BT连接的其他资源,并在可能的情况下释放它们.


这里要求的是如何强制关闭BluetoothServerSocket的ParcelFileDescriptor.当心:它可能会破坏事情!

您必须访问BluetoothServerSocketmSocket字段才能访问底层的BluetoothSocket.此BluetoothSocket在字段mPfd中保存ParcelFileDescriptor.在那你可以打电话.由于两个字段都不可见,您将不得不使用Reflections:close()

public void closePFD(BluetoothServerSocket closeMe) throws AllKindOfExceptionsThatYouHaveToHandle
{
    Field mSocketFld = closeMe.getClass().getDeclaredField("mSocket");
    mSocketFld.setAccessible(true);

    BluetoothSocket btsock = (BluetoothSocket)mSocketFld.get(closeMe);

    Field mPfdFld = btsock.getClass().getDeclaredField("mPfd");
    mPfdFld.setAccessible(true);

    ParcelFileDescriptor pfd = (ParcelFileDescriptor)mPfdFld.get(btsock);

    pfd.close();
}
Run Code Online (Sandbox Code Playgroud)

这将关闭BluetoothServerSocket.如果你想从BTServerSockets接受方法中只关闭BluetoothSocket,你可以省略获得mSocket的部分,如jitain sharmas answer所示.