2012-12-07 3 views
7

내 앱에서 Bluetooth를 사용하는 중에 문제가 있습니다. 28 BluetoothSocket/BluetoothServerSockets을 만든 후에 모든 포트가 사용 된 것 같습니다. 소켓을 동시에 열 필요는 없으며 Bluetooth가 활성화 된 이후로 소켓이 28 개 밖에 없습니다.Android : Bluetooth에서 포트 번호를 가져 오지 못했습니다.

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에서만 문제를 테스트하기 때문에 문제는 명확하게 관련되어 있는지 확실하지 않지만 명확하지는 않습니다.

적어도 내 장치에서는 Bluetooth 어댑터의 상태를 전환 할 때까지 다시 응용 프로그램을 시작할 수 없으므로 문제는 확실히 연결의 기본 관리에 있습니다.

여기에 재현 할 단계가있는 버그가 있습니다 (http://b.android.com). 나는 그것을 기쁘게 생각합니다.

+1

감사합니다. 여기에 버그를 제출했습니다. [# 41110] (http://code.google.com/p/android/issues/detail?id=41110). Galaxy Nexus와 4.2.1을 실행하는 Nexus 7 모두에서 앱이 다운되는 데 15 번 걸렸습니다. 내 넥서스 원은 결코 추락하지 않았으므로 단지 JB 문제 일뿐입니다. – mattprecious

0

최근에이 문제에 대한 해결책을 찾아야했습니다. Android 업그레이드는 옵션이 아닙니다.

연결이 설정/해제 될 때마다 mAcceptThread를 파괴하고 재생성하는 대신 원래 인스턴스를 유지하고 재사용 할 수 있습니다. 이렇게하면 앱에 대한 버그의 영향을 최소화 할 수 있습니다.() 함수는 AcceptThread 클래스에서

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;} 
... 
... 

을 실행에 루프를 수정 :

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

BluetoothChatService 파일에서

, 연결된() 함수에서, mAcceptThread을 취소하지 아이디어를 올바르게 구현하려면 코드에서 수행해야 할 다른 작업이있을 수 있습니다.

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

는 수용 스레드에 대한 null가 아닌 탐지를 추가하고 실패하지 THEAD 연결 :

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

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

을 아직도 내가 무작위로 연결이 떨어질 수 있지만, 서비스 재 연결하고 모든 작품.

관련 문제