Android:蓝牙无法获取端口号

我遇到了一个问题,在我的应用程序中使用蓝牙。 似乎在创build了28个BluetoothSocket / BluetoothServerSockets之后,所有的端口都被占用了。 不需要同时打开sockets,因为启用了蓝牙function,sockets只有28个。

这可以使用Android示例中提供的BluetoothChat示例进行重现。 只需打开和closures应用程序15次(应用程序每次创build2个套接字)。 在第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) 

套接字closures后有没有办法释放端口?

Solutions Collecting From Web of "Android:蓝牙无法获取端口号"

我可以在设备上validation这个行为, 尽pipe以相同方式崩溃所需的次数因设备而异(我认为Galaxy Nexus运行4.2时需要20-25次),所以端口句柄的可用数量似乎有所不同。 由于所有的BluetoothSocket实例都已经由Dalvik发布和closures,所以我还可以提供有关示例应用程序(或您的应用程序)中的内存泄漏问题的信息。 这里列出的步骤只是testingBluetoothServerSocket上的问题,所以不清楚问题是否与这个问题具体相关,尽pipe似乎不太可能。

至less在我的设备上,在切换蓝牙适配器的状态之前,您甚至不能再启动应用程序,所以问题肯定在于堆栈连接的底层pipe理。

我会提出一个错误的步骤来重现这里http://b.android.com ,我会很高兴upvote它。

最近,我不得不钻研一个解决scheme。 升级Android不是一个选项。

事实certificate,如果每次连接build立/中断时不破坏并重新创buildmAcceptThread,请保留原始实例并重新使用它。 这最大限度地减less了错误对你的应用程序的影响。

从BluetoothChatService文件中,在connected()函数中,不要取消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) 

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

要重新连接我使用片段中的定​​时处理程序:

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

为了解决“重新连接28次以上失败”的问题,我每次在丢失连接时都会重新启动服务:

 //BluetoothChatService.this.start(); 

我也注意到套接字closures的所有部分:

 //socket.close(); //mmServerSocket.close(); //mmSocket.close(); //mSecureAcceptThread.cancel(); 

并为接受线程添加了一个不为空的检测,并连接了不失败:

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

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

我仍然得到随机连接滴,但服务重新连接,一切正常。