2012-12-07 158 views
7

我在我的应用中遇到了使用蓝牙的问题。看起来已经创建了28个BluetoothSocket/BluetoothServerSockets之后,所有的端口都被占用了。不需要同时打开套接字,自启用蓝牙功能以来,套接字只有28个。Android:蓝牙无法获取端口号

这可以使用Android Samples中提供的BluetoothChat示例进行复制。只需打开和关闭应用程序15次(应用程序每次创建2个套接字)。在15日的时候,它会崩溃,并会继续崩溃,直到您禁用,然后重新启用蓝牙:

12-06 18:43:58.177: E/BluetoothSocket(18530): bindListen, fail to get port number, exception: java.io.IOException: read failed, socket might closed, read ret: -1 
12-06 18:43:58.193: E/BluetoothChatService(18530): Socket Type: Insecurelisten() failed 
12-06 18:43:58.193: E/BluetoothChatService(18530): java.io.IOException: Error: -1 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.bluetooth.BluetoothAdapter.createNewRfcommSocketAndRecord(BluetoothAdapter.java:1035) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.bluetooth.BluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(BluetoothAdapter.java:982) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.example.android.BluetoothChat.BluetoothChatService$AcceptThread.<init>(BluetoothChatService.java:280) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.example.android.BluetoothChat.BluetoothChatService.start(BluetoothChatService.java:119) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.example.android.BluetoothChat.BluetoothChat.onResume(BluetoothChat.java:131) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1185) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.Activity.performResume(Activity.java:5182) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2732) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2771) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2235) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.access$600(ActivityThread.java:141) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.os.Looper.loop(Looper.java:137) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.main(ActivityThread.java:5039) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at java.lang.reflect.Method.invokeNative(Native Method) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at java.lang.reflect.Method.invoke(Method.java:511) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at dalvik.system.NativeStart.main(Native Method) 

有什么办法来释放口插座关闭后?

回答

6

我可以在我有这里的设备上验证此行为;尽管以同样方式崩溃所需的次数因设备而异(我认为Galaxy Nexus运行4.2时需要20-25次),所以可用的端口句柄数似乎有所不同。我还可以提供这样的信息,即示例应用程序(或您的应用程序)中的问题不是内存泄漏,因为Dalvik已发布并关闭了BluetoothSocket的所有实例。此处列出的步骤仅测试BluetoothServerSocket上的问题,因此它不清楚问题是否与该问题具体相关,尽管似乎不太可能。

至少在我的设备上,您甚至无法再次启动应用程序,直到切换蓝牙适配器的状态,所以问题肯定在堆栈连接的基础管理中。

我会提交一个步骤来重现这里的错误http://b.android.com的错误,我很乐意为它付出代价。

+1

感谢您的关注!我在这里提交了一个错误:[#41110](http://code.google.com/p/android/issues/detail?id=41110)。在Galaxy Nexus和运行4.2.1的Nexus 7上,该应用崩溃了15次。我的Nexus One从未坠毁,所以希望这只是一个JB问题。 – mattprecious

0

最近,我不得不钻研为此提出解决方案。升级Android不是一种选择。

事实证明,如果每次连接建立/中断时不是销毁并重新创建mAcceptThread,而是保留原始实例并重新使用它。这最大限度地减少了错误对你的应用程序的影响。

从BluetoothChatService文件,在连接()函数,不取消mAcceptThread:

public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { 
... 
... 
... 
// Cancel the accept thread because we only want to connect to one device 
//(Rather stay listening so comment out the cancel line!!) 
//If necessary, use some other state to prevent a second connection. 
//DONT CANCEL: if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;} 
... 
... 

在AcceptThread类,修改环路在run()函数:

  // Listen to the server socket if we're not connected 
//OLD LOOP:   while (mState != STATE_CONNECTED) 
//(Rather use STATE_NONE so the loop will only stop when the service does) 
      while (mState != STATE_NONE) 

在你的代码中可能还有其他的事情要做,以正确地实现这个想法。

0

重新连接我在片段定时处理程序使用方法:

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(MainActivity.mac); 
        // Attempt to connect to the device 
        mChatService.connect(device, true); 

为了解决这个问题,“失败时重新连接超过28次”我评论每一次的服务重新启动当自身失去连接:

//BluetoothChatService.this.start(); 

还我注释掉所有部件在插座关闭:

//socket.close(); 

//mmServerSocket.close(); 

//mmSocket.close(); 

//mSecureAcceptThread.cancel(); 

,并增加了对接受线程不为空​​探测和连接的tHead没有失败:

if(mAdapter != null) { 
         tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, 
           MY_UUID_SECURE); 
        }else{ 
         mAdapter = BluetoothAdapter.getDefaultAdapter(); 
         //mState = STATE_NONE; 
        } 

if(mmServerSocket != null) { 
         socket = mmServerSocket.accept(); 
        } 

我仍然看到一些随机的连接断开,但服务重新连接并一切正常。