2017-11-09 20 views
0

私はandroid devのプロジェクトに取り組んでいます。 BluetoothChatのウェブサイトでは、メッセージを正しく送信しているようですが、受信していないようです。以前は 私は別のBluetoothアプリケーションを作成しようとしましたが、デバイスに接続するときに、接続を確認するように求められ、ピンコードが提示されました。現在のアプリケーションで作業しているときは、私は決してプロンプトを与えられません。しかし、例外を打つことはなく、メッセージは送信されているようです。ここに私のThreadクラスには、接続を管理するためのものである:Bluetoothチャットでメッセージが受信されません。ハンドラは壊れていますか?

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

私はちょうど私のミスがどこにあるかわかりません。私はそれがメッセージを送る方法に問題があると思っていたのですか?しかし、私がデバッガで自分のコードをステップ実行すると、私は実際には何も見えません。今は問題が受信デバイスの最後にあると思っていますが、何も受信しないようです。私も私のハンドラとbroadcastReceiverを掲載します:ここでは

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です:

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

} 

あなたが何かを見つけることができるしている場合は私に知らせてください。私は本当に助けに感謝します。また、元のコードがJavaであることを言及する必要があります。私はコトリンに私のことを書いています。

+0

これはGoogleサンプルBluetoothチャットに基づいていると仮定すると、あなたの 'AcceptThread'はどのように見えますか? –

+0

@MorrisonChang私は今すぐAcceptThreadのコードを編集しました。はい、これはGoogleのサンプルに基づいています。 –

答えて

0

私のwhileループが問題だったことが判明しました。 while(mState!=STATE_CONNECTEDループは、run()関数本体の残りの部分を囲む必要があります。だから解決策は中括弧を動かすだけだった。時にはそれは小さなものです。しかし、いつ私の表現で助けてくれてありがとう。

3

あなたのKotlin whenブロックがJavaコードから関数を複製していないことに気付きました。

Kotlin:

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

は、Javaコードではありません。

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

あなたKotlinコードは次のようになります。

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

のないブランチの分岐は、プログラムがbreakに達するまでコードの次の行に分岐しますが、Kotlinでは矢印/中括弧がブランチを定義します。 when文をすべてダブルチェックして、期待されるJava switchの動作に従っていることを確認してください。

+0

私はあなたが示唆した変更を加えましたが、まだ違いは見られません。プロンプトを接続するデバイスを許可しないと何かすることができますか?私はそれを見ているべきですか? –

+0

KotlinでBluetoothチャットアプリを書き直すだけの場合は、プロンプトの動作が同じになるはずです。 「即時実行」を無効にしたり、アプリを削除して確実に削除することができます。 1つのアプローチは、JavaとKotlinのバージョン間の行ごとに、あなたのKotlinコードで 'when'ブランチの問題に類似する他の違いがあるかどうかを調べることです。もう1つは、より多くのロギングを実行してJavaバージョンを再実行し、Kotlinバージョンで同じ手順を繰り返すことです。十分なログがあれば、エラーを指摘するいくつかの相違点が現れるはずです。 –

関連する問題