且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Android的蓝牙连接失败后,489成功连接

更新时间:2023-09-28 22:58:16

这个问题似乎连接到的的限制文件描述符的设备上。有一个报告,这里 这个问题 P>

在创建蓝牙套接字一个新的fd是

从系统中得到了两个新的函数依赖。看来你不关闭你的previous BT连接正确,以便使用的文件描述符的数量不断增加,直到达到最大极限。

要避免这一点,你至少得叫关闭()上的 BluetoothServerSocket 的你收到 listenUsingRfcommWithServiceRecord完成操作的后()通话。您也应该检查,如果你持有到连接到BT有关的其他资源,如果可能的话让他们***。


由于这是在这里要求是如何强制BluetoothServerSocket的ParcelFileDescriptor闭幕。 小心:它可能会破坏东西

您将要访问的 mSocket 的领域中的 BluetoothServerSocket 的访问底层的的BluetoothSocket 的。这的的BluetoothSocket 的持有外地MPFD的ParcelFileDescriptor。而在这你可以调用关闭()。由于这两个领域是不可见的,你将不得不使用的的思考的:

 公共无效closePFD(BluetoothServerSocket closeMe)抛出AllKindOfExceptionsThatYouHaveToHandle
{
    现场mSocketFld = closeMe.getClass()getDeclaredField(mSocket)。
    mSocketFld.setAccessible(真正的);

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

    现场mPfdFld = btsock.getClass()getDeclaredField(MPFD)。
    mPfdFld.setAccessible(真正的);

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

    pfd.close();
}
 

这将关闭的 BluetoothServerSocket 的。如果你想关闭刚刚的的BluetoothSocket 的从BTServerSockets接受的方法,你可以离开了越来越部分的 mSocket 的作为的 jitain sharmas回答

unfortunately, I have some problems with android's bluetooth. For my test environment I use a Nexus 4 with Android 4.4.2.

I have a Java Application on my PC, which uses bluecove in order to make a SPP connection as client. The programme is looking for a special service name and connects with my android phone. Afterwards it sends 72 bytes to my android phone and waits for an answer. When getting that answer the programme sleeps for 3 seconds and than starts again.

On my android phone I have an application with background bluetooth listener which starts at boot. This application is based on BluetoothChat sample demo. When receiving bluetooth data I check incoming data and send back an answer.

All that is working fine. But after 489 bluetooth connections the android app fails with following error snippet while PC-java-app is going on:

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)

So the app has a problem with the ParcelFileDescriptor, which is suddenly null. But why?

All the described above also happens when changing pause-time on PC-java-app, using various data sizes for transmitting and using different smartphones. When using reflection "listenUsingRfcommWithServiceRecord" the same happens after 505 transmissions. Also using wakelock changes nothing.

By the way, I got the same behaviour when using BluetoothChat sample.

So, has anybody a hint, what happens?

Update:

BluetoothServerSocket is closed after each connection and BluetoothSocket if bluetooth state is 3.

The problem seems connected to the limit of file descriptors on your device. There is a report for that issue here

During the creation of a Bluetooth socket a new fd is two new FDs are acquired from the system. It seems you are not closing your previous BT connections correctly so the number of used FDs steadily increases until you hit the limit.

To avoid this you will at least have to call close() on the BluetoothServerSocket you receive from the listenUsingRfcommWithServiceRecord() call after finishing the operations for it. You should also check if you are holding on to other resources connected to the BT connection and free them if possible.


As it was requested here is how to force the closing of the ParcelFileDescriptor of the BluetoothServerSocket. Beware: it may break things!

You will have to access the mSocket field of the BluetoothServerSocket to access the underlying BluetoothSocket. This BluetoothSocket holds the ParcelFileDescriptor in the field mPfd. And on that you can call close(). As both fields are not visible you will have to use Reflections:

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();
}

This will close the BluetoothServerSocket. If you want to close just the BluetoothSocket from the BTServerSockets accept method you can leave out the part of getting mSocket as seen in jitain sharmas answer.