Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
117 views
in Technique[技术] by (71.8m points)

android studio - Accessing Handler from thread in Service

I'm using a messenger to bind to a service in order to get a two-way communication between my activity and my service.

My service is running in background and runs a bluetooth communication. I'm already able to send data to the BluetoothService, which can send it trough Bluetooth. I can receive data Through Bluetooth and print it the terminal. Now I want to send back this data to the UI. I've tried to implement a counter when reaches 10 it sends back the information from my BluetoothService to my TestActivity which is working quite well.
I can't figure out how to do that, if someone can help it would be a great pleasure.

TestActivity :

    class TestActivity : AppCompatActivity() {



    /** Flag indicating whether we have called bind on the service.  */
    private var bound: Boolean = false



    //////
    // Messenger on the server
    private var mService: Messenger? = null
    // Messenger on the client
    lateinit var mMessenger: Messenger

    // Signal sent to the server
    private val SIG_SEND_PLUS = 0
    private val SIG_GET_UPDATE = 1





    /**
     * Class for interacting with the main interface of the service.
     */
    private val mConnection = object : ServiceConnection {


        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = Messenger(service)
            bound = true
        }

        override fun onServiceDisconnected(className: ComponentName) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null
            bound = false
        }
    }


    inner class ClientHandler : Handler() {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                SIG_GET_UPDATE ->
                    //changeTextView()
                    Toast.makeText(applicationContext, "Upgrade", Toast.LENGTH_SHORT).show()
            }
        }
    }






    private fun sendMsg(stringToSend: String) {
        if (!bound) return
        // Create and send a message to the service, using a supported 'what' value
        val msg: Message = Message.obtain(null, SEND_MSG, 0, 0, stringToSend)
        try {
            mService?.send(msg)
        } catch (e: RemoteException) {
            e.printStackTrace()
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)



        buttonSend.setOnClickListener {
            sendMsg(editTextTextPersonName.text.toString())
            //sayHello()
        }
        buttonStart.setOnClickListener {

            mMessenger = Messenger(ClientHandler())
            // Binding service
            bindService(
                Intent(this, BluetoothService::class.java),
                mConnection,
                Context.BIND_AUTO_CREATE
            )
        }

        //+1
        button.setOnClickListener {
            if (mService != null) {
                try {
                    val message = Message.obtain(null, SIG_SEND_PLUS)
                    val bundle = Bundle()
                    bundle.putInt("value", 1)
                    message.data = bundle
                    message.replyTo = mMessenger
                    mService!!.send(message)
                } catch (e: RemoteException) {
                    e.printStackTrace()
                }
            }
        }

    }

    override fun onStart() {
        super.onStart()

    }

    override fun onStop() {
        super.onStop()
        // Unbind from the service
        if (bound) {
            unbindService(mConnection)
            bound = false
        }
    }
}

BluetoothService :

class BluetoothService : Service(){
    companion object {


        var m_UUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
        private const val MAC_ADDRESS = "00:0E:EA:CF:53:B5"
        var m_bluetoothSocket: BluetoothSocket? = null

        const val TAG = "Tag"




        // Defines several constants used when transmitting messages between the
// service and the UI.
        private const val SIG_GET_PLUS = 0
        private const val SIG_SEND_UPDATE = 1
        private const val SEND_MSG = 2


        lateinit var m_bluetoothAdapter: BluetoothAdapter
        var m_isConnected: Boolean = false



    }




    lateinit var messenger: Messenger
    private var sum = 0
    lateinit var mClient: Messenger





    inner class ServiceHandler : Handler() {
        override fun handleMessage(msg: Message) {
            // Process the message


            when (msg.what) {
                SEND_MSG ->
                    ConnectedThread(m_bluetoothSocket!!).write(msg.obj.toString())
                SIG_GET_PLUS -> {
                    val bundle = msg.data
                    sum += bundle.getInt("value")
                    Toast.makeText(applicationContext, sum.toString() + "", Toast.LENGTH_SHORT)
                        .show()
                    // =10 Send a message to the client
                    mClient = msg.replyTo
                    if (null == mClient) {
                        return
                    }
                    else if (sum == 10) {
                        val message =
                            Message.obtain(null, SIG_SEND_UPDATE)
                        try {
                            mClient.send(message)

                        } catch (e: RemoteException) {
                            e.printStackTrace()
                        }
                    }
                }
                else -> {
                }
            }
        }


    }




    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    override fun onBind(intent: Intent): IBinder? {
        Toast.makeText(applicationContext, "binding", Toast.LENGTH_SHORT).show()

        messenger = Messenger(ServiceHandler())
        //Start bluetooth connection
        ConnectThread().start()

        return messenger.binder


    }





    private class ConnectThread() : Thread() {
        private var connectSuccess: Boolean = true
        public override fun run() {

            try {
                if (m_bluetoothSocket == null || !m_isConnected) {
                    Companion.m_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
                    val device: BluetoothDevice = Companion.m_bluetoothAdapter.getRemoteDevice(MAC_ADDRESS)
                    m_bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(m_UUID)
                    BluetoothAdapter.getDefaultAdapter().cancelDiscovery()
                    m_bluetoothSocket!!.connect()
                    ConnectedThread(m_bluetoothSocket!!).start()
                }
            } catch (e: IOException) {
                connectSuccess = false
                e.printStackTrace()
            }

        }

        // Closes the client socket and causes the thread to finish.
        fun cancel() {

            if(ControlActivity.m_bluetoothSocket != null){
                try {
                    ControlActivity.m_bluetoothSocket!!.close()
                    ControlActivity.m_bluetoothSocket = null
                    ControlActivity.m_isConnected = false
                } catch (e : IOException){
                    e.printStackTrace()
                }

            }
        }
    }






    private class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {

        private val mmInStream: InputStream = mmSocket.inputStream
        private val mmOutStream: OutputStream = mmSocket.outputStream
        private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream

        override fun run() {
            var numBytes: Int // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs.
            while (true) {
                // Read from the InputStream.


                if (mmInStream.available()>0) {
                    numBytes = try {
                        mmInStream.read(mmBuffer)


                    } catch (e: IOException) {
                        Log.d(TAG, "Input stream was disconnected", e)
                        break
                    }

                    val readMessage = String(mmBuffer, 0, numBytes)

                    println(readMessage)
                }
                else {
                    SystemClock.sleep(100)

                }
            }
        }
        // Call this from the main activity to send data to the remote device.
        fun write(string : String) {
            try {
                mmOutStream.write(string.toByteArray())
            } catch (e: IOException) {
                Log.e(TAG, "Error occurred when sending data", e)

                return
            }
        }

        // Call this method from the main activity to shut down the connection.
        fun cancel() {
            try {
                mmSocket.close()
            } catch (e: IOException) {
                Log.e(TAG, "Could not close the connect socket", e)
            }
        }
   }
}
question from:https://stackoverflow.com/questions/65647443/accessing-handler-from-thread-in-service

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...