2012-12-07 12 views
7

Tôi đang gặp sự cố khi sử dụng Bluetooth trong ứng dụng của mình. Có vẻ như sau khi 28 BluetoothSocket/BluetoothServerSockets đã được tạo, tất cả các cổng đều được lấy. Các ổ cắm không cần phải được mở đồng thời, nó chỉ là 28 ổ cắm kể từ khi Bluetooth được kích hoạt.Android: Bluetooth không nhận được số cổng

Điều này có thể được sao chép bằng mẫu BluetoothChat được cung cấp trong Android Samples. Chỉ cần mở và đóng ứng dụng 15 lần (ứng dụng tạo 2 ổ cắm mỗi lần). Vào lần thứ 15, thiết bị sẽ gặp lỗi và sẽ tiếp tục bị lỗi cho đến khi bạn tắt rồi bật lại Bluetooth:

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) 

Có cách nào để giải phóng các cổng sau khi đóng socket?

Trả lời

6

Tôi có thể xác minh hành vi này trên thiết bị mà tôi có ở đây; mặc dù số lần cần thiết để sụp đổ theo cùng một cách khác nhau tùy theo thiết bị (tôi nghĩ rằng 20-25 lần được yêu cầu trên Galaxy Nexus chạy 4.2) do đó số lượng có sẵn của cổng xử lý có vẻ khác nhau. Tôi cũng có thể đóng góp thông tin rằng vấn đề không phải là rò rỉ bộ nhớ trong ứng dụng mẫu (hoặc ứng dụng của bạn cho vấn đề đó) vì tất cả các trường hợp của BluetoothSocket đã được Dalvik phát hành và đóng. Các bước được liệt kê ở đây chỉ kiểm tra vấn đề trên BluetoothServerSocket, do đó, không rõ ràng nếu vấn đề có liên quan cụ thể đến điều đó, mặc dù có vẻ như không chắc chắn.

Ít nhất trên thiết bị của tôi, bạn thậm chí không thể khởi động lại ứng dụng cho đến khi chuyển sang trạng thái bộ điều hợp Bluetooth, vì vậy vấn đề chắc chắn là trong việc quản lý cơ bản các kết nối trên ngăn xếp.

Tôi sẽ gửi một lỗi với các bước để tạo lại ở đây http://b.android.com và tôi rất vui khi được thăng hạng.

+1

Cảm ơn bạn đã xem! Tôi đã gửi một lỗi ở đây: [# 41110] (http://code.google.com/p/android/issues/detail?id=41110). Mất 15 lần để phá ứng dụng trên cả Galaxy Nexus và Nexus 7 của tôi chạy 4.2.1. Nexus One của tôi không bao giờ bị rơi, vì vậy hy vọng nó chỉ là một vấn đề JB. – mattprecious

0

Gần đây, tôi đã phải nghiên cứu để tìm ra giải pháp cho việc này. Nâng cấp Android không phải là một tùy chọn.

Nó chỉ ra rằng nếu thay vì phá hủy và tạo lại mAcceptThread mỗi khi kết nối được thiết lập/bị hỏng, hãy giữ nguyên bản gốc và sử dụng lại nó. Điều này giảm thiểu hiệu ứng của lỗi trên ứng dụng của bạn.

Từ file BluetoothChatService, trong hàm kết nối(), không hủy bỏ 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;} 
... 
... 

Trong lớp AcceptThread, sửa đổi vòng lặp trong run() chức năng:

  // 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) 

Có thể có những thứ khác cần làm trong mã của bạn để triển khai đúng ý tưởng.

0

Để tái kết nối tôi sử dụng trong một handler theo thời gian trong đoạn:

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

Để giải quyết vấn đề này "không thành công khi tái kết nối cho hơn 28 lần" tôi nhận xét mỗi khi dịch vụ tái khởi động bản thân khi mất kết nối:

//BluetoothChatService.this.start(); 

cũng i nhận xét ra tất cả các phần mà các ổ cắm đóng cửa:

//socket.close(); 

//mmServerSocket.close(); 

//mmSocket.close(); 

//mSecureAcceptThread.cancel(); 

và thêm một phát hiện không null cho chấp nhận đề và kết nối thead không để thất bại:

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

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

tôi vẫn nhận được kết nối ngẫu nhiên giảm, nhưng dịch vụ tái kết nối và mọi thứ hoạt động.