Android的蓝牙连接失败后,489成功连接 [英] android bluetooth connection fails after 489 successful connections

查看:1402
本文介绍了Android的蓝牙连接失败后,489成功连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不幸的是,我有一些问题,Android的蓝牙。对于我的测试环境,我用一台Nexus 4与Android 4.4.2。

我有一个Java应用程序在我的电脑,这在为了使SPP连接,客户端使用bluecove上。该方案是在寻找一个特殊的服务名称,并与我的Andr​​oid手机连接。此后,它发送72字节到我的Andr​​oid手机,等待一个答案。当得到这个问题的答案方案睡3秒,比重新开始。

在我的Andr​​oid手机,我有背景的蓝牙监听器,在开始启动的应用程序。这个申请是基于BluetoothChat样品演示。当接收蓝牙数据我检查接收数据并发送回一个答案。

所有这一切工作正常。但经过489蓝牙连接的Andr​​oid应用程序失败,以下错误代码段,而PC-java的应用程序,是怎么回事:

  getBluetoothService()调用时没有BluetoothManagerCallback
关闭虚拟机
主题ID = 1:螺纹未捕获异常退出(组= 0x41b34ba8)
致命异常:主要
工艺:de.tum.lme.diamantum:remote_blue,PID:21567
显示java.lang.NullPointerException:当前FileDescriptor不能为空
    在android.os.ParcelFileDescriptor< INIT>(ParcelFileDescriptor.java:174)
    在android.os.ParcelFileDescriptor $ 1.createFromParcel(ParcelFileDescriptor.java:905)
    在android.os.ParcelFileDescriptor $ 1.createFromParcel(ParcelFileDescriptor.java:897)
    在android.bluetooth.IBluetooth $存根$ Proxy.createSocketChannel(IBluetooth.java:1355)
    在android.bluetooth.BluetoothSocket.bindListen(BluetoothSocket.java:349)
    在android.bluetooth.BluetoothAdapter.createNewRfcommSocketAndRecord(BluetoothAdapter.java:1055)
    在android.bluetooth.BluetoothAdapter.listenUsingRfcommWithServiceRecord(BluetoothAdapter.java:976)
    在com.test.btconn.BluetoothHandling $ AcceptThread< INIT>(BluetoothHandling.java:449)
    在com.test.btconn.BluetoothHandling.start(BluetoothHandling.java:216)
    在com.test.btconn.BluetoothListenerService.setupBtSockets(BluetoothListenerService.java:330​​)
    在com.test.btconn.BluetoothListenerService.manageBtState(BluetoothListenerService.java:249)
    在com.test.btconn.BluetoothListenerService.setBtStateDisconnected(BluetoothListenerService.java:383)
    在com.test.btconn.BluetoothListenerService.access $ 5(BluetoothListenerService.java:378)
    在com.test.btconn.BluetoothListenerService $ 2.handleMessage(BluetoothListenerService.java:421)
 

因此​​,应用程序有与ParcelFileDescriptor,这是突然空了问题。但是,为什么?

所有的上述变化时,对PC-java的应用程序的暂停时间,使用各种大小的数据传输,并使用不同的智能手机也恰好。当使用反射listenUsingRfcommWithServiceRecord后505传输同样的情况。还利用wakelock改变什么。

顺便说一句,我使用BluetoothChat样品时,得到了同样的行为。

那么,有没有人暗示,会发生什么情况?

更新:

BluetoothServerSocket的每个连接的BluetoothSocket后关闭,如果蓝牙状态为3。

解决方案

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

在创建蓝牙套接字一个新的fd是 <一的href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.4.2_r1/android/os/ParcelFileDescriptor.java/#899"相对=nofollow> 从系统中得到了两个新的函数依赖。看来你不关闭你的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.

这篇关于Android的蓝牙连接失败后,489成功连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆