2017-11-09 6 views
0

나는 android dev에있는 프로젝트에서 일하고있다. BluetoothChat에 대한 웹 사이트 및 메시지를 제대로 보내고 있지만받지 못하는 것 같습니다. 과거에 다른 블루투스 앱을 만들려고했는데 기기에 연결할 때 연결을 확인하고 핀 코드가 표시되었습니다. 현재 앱에서 작업 할 때 프롬프트가 표시되지 않습니다. 그러나, 그것은 어떤 예외도 치지 않고 있고 메시지는 보내는 것처럼 보인다. 여기에 연결을 관리하기위한 내 스레드 클래스 :블루투스 채팅에서 메시지를 수신하지 못했습니다. 내 처리기가 고장 났는가?

inner class ConnectedThread(val socket:BluetoothSocket, val socketType:String) : Thread(){ 

    val inStream = socket.inputStream 
    val outStream = socket.outputStream 

    init { 
     mState = STATE_CONNECTED 
    } 

    override fun run() { 
     Log.i(TAG, "BEGIN mConnectedThread") 
     val buffer = ByteArray(1024) 
     var bytes:Int 

     while (mState == STATE_CONNECTED){ 
      try { 
       bytes = inStream.read(buffer) 

       mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer) 
         .sendToTarget() 
      }catch (ioe:IOException){ 
       Log.e(TAG, "disconnected", ioe) 
       connectionLost() 
       break 
      } 
     } 
    } 

    fun write(buffer:ByteArray){ 
     try { 
      outStream.writeMessage(buffer, mHandler) 
     }catch (ioe:IOException){ 
      Log.e(TAG, "Exception during write", ioe) 
     } 
    } 

    fun cancel(){ 
     try { 
      socket.close() 
     }catch (ioe:IOException){ 
      Log.e(TAG, "close of connect socket failed", ioe) 
     } 
    } 
} 

} 

은 내가 아래에있는 확장 기능은 OutputStream에 쓰는 데 사용 :

fun OutputStream.writeMessage(buffer:ByteArray, handler:Handler? = null){ 
write(buffer) 

handler?.let { 
    it.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer) 
      .sendToTarget() 
} 
} 

난 그냥 내 실수가 어디 있는지 모르겠습니다. 제가 메시지를 보내는 방식에 문제가 있다고 생각 했나요? 그러나 디버거로 코드를 단계별로 실행할 때 실제로는 아무 것도 볼 수 없습니다. 이제는 아무 것도받지 못하는 수신 장치의 끝에 문제가 있다고 생각합니다. 나뿐만 아니라 내 처리기 및 브로드 캐스트 리시버를 게시 할 예정입니다 :

inner class AcceptThread(val secure:Boolean) : Thread(){ 
    var mmServerSocket:BluetoothServerSocket? = null 
    val mSocketType:String = if (secure) "Secure" else "Insecure" 

    init { 
     try { 
      mmServerSocket = if (secure){ 
       mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_SECURE) 
      } else { 
       mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, UUID_INSECURE) 
      } 
     }catch (ioe:IOException){ 
      Log.e(TAG, "Socket Type: $mSocketType listen() failed", ioe) 
     } 
     mState = STATE_LISTEN 
    } 

    override fun run() { 
     Log.d(TAG, "Socket Type: $mSocketType BEGIN $this") 
     name = "AcceptThread $mSocketType" 

     var socket:BluetoothSocket? = null 

     while (mState!=STATE_CONNECTED){ 
      try { 
       socket = mmServerSocket!!.accept() 
      }catch (ioe:IOException){ 
       Log.e(TAG, "Socket Type: $mSocketType accept failed", ioe) 
       break 
      } 
     } 

     socket?.let { 
      synchronized([email protected]){ 
       when(mState){ 
        STATE_LISTEN -> {} 
        STATE_CONNECTING -> { 
         connected(socket!!, socket!!.remoteDevice, mSocketType) 
        } 
        STATE_NONE -> {} 
        STATE_CONNECTED -> { 
         try { 
         it.close() 
        }catch (ioe:IOException){ 
         Log.e(TAG, "Could not close unwanted socket", ioe) 
         } 
        } 
        else->{throw BluetoothChatServiceException("Invalid Service State")} 
       } 
      } 
     } 
     Log.i(TAG, "End mAcceptThread, Socket Type: $mSocketType") 
    } 

    fun cancel(){ 
     Log.d(TAG, "Socket Type: $mSocketType cancel $this") 
     try { 
      mmServerSocket!!.close() 
     }catch (ioe:IOException){ 
      Log.e(TAG, "Socket Type: $mSocketType close() of server failed", ioe) 
     } 
    } 

} 

당신은 아무것도를 발견 할 수 있다면 알려 주시기 바랍니다 :

val mHandler = object:Handler(){ 
    override fun handleMessage(msg: Message?) { 
     when(msg!!.what) { 
      Constants.MESSAGE_STATE_CHANGE -> { 
       when(msg.arg1) { 
        BluetoothChatService.STATE_CONNECTED -> { 
         setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)) 
         mConversationArrayAdapter!!.clear() 
        } 
        BluetoothChatService.STATE_CONNECTING -> { 
         setStatus(getString(R.string.title_connecting)) 
        } 
        BluetoothChatService.STATE_LISTEN -> { 
        } 
        BluetoothChatService.STATE_NONE -> { 
         setStatus(getString(R.string.title_not_connected)) 
        } 
       } 
      } 
      Constants.MESSAGE_WRITE -> { 
       val writeBuf = msg.obj as ByteArray 
       val writeMessage = String(writeBuf) 
       mConversationArrayAdapter!!.add("Me: $writeMessage") 
      } 
      Constants.MESSAGE_READ -> { 
       val readBuf = msg.obj as ByteArray 
       val readMessage = String(readBuf, 0, msg.arg1) 
       mConversationArrayAdapter!!.add("$mConnectedDeviceName: $readMessage") 
      } 
      Constants.MESSAGE_DEVICE_NAME -> { 
       mConnectedDeviceName = msg.data.getString(Constants.DEVICE_NAME) 
       if (activity!=null)Toast.makeText(activity, "Connected to $mConnectedDeviceName", Toast.LENGTH_SHORT).show() 
      } 
      Constants.MESSAGE_TOAST -> { 
       if (activity!=null)Toast.makeText(activity, msg.data.getString(Constants.TOAST), Toast.LENGTH_SHORT).show() 
      } 
     } 
    } 
} 

val mReceiver:BroadcastReceiver = object:BroadcastReceiver(){ 
    override fun onReceive(context: Context, intent: Intent) { 
     val action = intent.action 

     if (BluetoothDevice.ACTION_FOUND.equals(action)){ 
      val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE) 
      if (device.bondState!=BluetoothDevice.BOND_BONDED){ 
       mNewDevicesArrayAdapter.add("${device.name} \n ${device.address}") 
      } 
     }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){ 
      setProgressBarIndeterminateVisibility(false) 
      setTitle(R.string.select_device) 
      if (mNewDevicesArrayAdapter.count==0){ 
       val noDevices = resources.getText(R.string.none_found).toString() 
       mNewDevicesArrayAdapter.add(noDevices) 
      } 
     } 
    } 

} 

것은 여기뿐만 아니라 내 AcceptThread입니다. 나는 정말로 도움을 감사 할 것이다. 또한 원래 코드는 자바로 언급해야합니다. 나는 Kotlin에 내 것을 쓰고있다.

+0

Google 샘플 블루투스 채팅을 기반으로한다고 가정하면 'AcceptThread'모양은 무엇입니까? –

+0

@MorrisonChang 필자는 AcceptThread의 코드를 지금 편집본에 게시했으며, 예, Google 샘플을 기반으로합니다. –

답변

0

내 while 루프 문제가 발생했습니다. while(mState!=STATE_CONNECTED 루프는 나머지 run() 함수 본문을 포함해야합니다. 그래서 해결책은 중괄호를 움직이는 것이 었습니다. 때때로 그것은 작은 것들입니다. 하지만 제 표현식에 대한 도움을 주셔서 감사합니다.

3

Kotlin when 블록이 Java 코드에서 함수를 복제하지 않는 것으로 나타났습니다.

코 틀린 :

when (mState) { 
    STATE_LISTEN -> {} 
    STATE_CONNECTING -> { 
     connected(socket!!, socket!!.remoteDevice, mSocketType) 
    } 
... 

는 자바 코드가 아닙니다 :

switch (mState) { 
    case STATE_LISTEN: 
    case STATE_CONNECTING: 
     // Situation normal. Start the connected thread. 
     connected(socket, socket.getRemoteDevice(), mSocketType); 
     break; 
... 

하지만,이 대신이다

switch (mState) { 
    case STATE_LISTEN: 
     break; 
    case STATE_CONNECTING: 
     // Situation normal. Start the connected thread. 
     connected(socket, socket.getRemoteDevice(), mSocketType); 
     break; 
... 

귀하의 코 틀린 코드가 있어야한다 :

when (mState) { 
    STATE_LISTEN, STATE_CONNECTING -> { 
     connected(socket!!, socket!!.remoteDevice, mSocketType) 
    } 
... 

break이없는 이없는 분기 코드는 break에 도달 할 때까지 다음 코드 행으로 넘어 가고 Kotlin에서는 화살표/중괄호가있는 항목이 분기를 정의합니다. when 문을 모두 두 번 확인하여 예상 한 Java switch 동작을 따르고 있는지 확인하십시오.

+0

나는 당신이 제안한 변화를 만들었지 만 나는 여전히 차이점을 보지 못하고있다. 그것은 프롬프트 장치를 연결하는 장치를받지 못하는 것과 관련이 있을까요? 나는 그것을 볼 수 있어야 하는가? –

+0

Kotlin에서 Bluetooth 채팅 응용 프로그램을 다시 작성하는 경우 프롬프트 동작이 동일해야합니다. '즉시 실행'을 사용 중지하거나 앱을 삭제하기 만하면됩니다. 하나의 접근법은 Java와 Kotlin 버전 사이에서 줄을 서서 Kotlin 코드에서'when' 분기 문제와 유사한 다른 차이점이 있는지 확인하는 것입니다. 또 하나는 더 많은 로깅을 사용하여 Java 버전을 재실행 한 다음 Kotlin 버전으로 동일한 단계를 반복하는 것입니다. 충분한 로깅을 사용하면 오류를 가리키는 몇 가지 차이점이 나타납니다. –