'Kotlin android bluetooth - send command - official Google tutorial explanation
I try program app control car via bluetooth on Android. I did everything like in tutorial for developer from Google. I stucked on "transfer Blueetooth data". Here is my code:
package com.example.piratsilnic
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.ContentValues.TAG
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import java.io.IOException
import java.util.*
class ZavodnikO : AppCompatActivity() {
var smer: Int = 50
val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
private inner class ConnectThread() : Thread() {
var car: BluetoothDevice = bluetoothAdapter!!.getRemoteDevice("98:D3:31:FB:1C:66")
private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
car.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
}
public override fun run() {
bluetoothAdapter?.cancelDiscovery()
mmSocket?.let { socket ->
Log.i("client", "Connecting")
socket!!.connect()
//manageMyConnectedSocket(socket)
}
}
fun cancel() {
try {
mmSocket?.close()
} catch (e: IOException) {
Log.e(TAG, "Could not close the client socket", e)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_zavodnik_o)
ConnectThread().run()
val smerSeek = findViewById<SeekBar>(R.id.SmerSeek)
smerSeek.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
smer = smerSeek.progress
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
//neco tu mozna nekdy bude
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
//neco tu mozna nekdy bude
}
})
smer = 50
}
}
It connect to the car and stay connected. And now I dont know how to implement class to send command.
I tried make fun in this class, that doesnt work.
In official tutorial (link here: https://developer.android.com/guide/topics/connectivity/bluetooth/transfer-data) they create special class and thread for that. But I cant understand how they did id. Can you please explanate to me, how it works? I dont get it what the handler do in the function? How to put socket like argument to the sending function? Why sending fun cant be in my function?
Or how to send messeges other way?
Thank you for anything. I wanna figure it out...
Solution 1:[1]
The handler is used to pass message from thread to UI activity. You can create another class to Transfer data.
private inner class SendReceive(private val mmSocket:BluetoothSocket):Thread(){
private val mmInPutStream:InputStream = mmSocket.inputStream
private val mmOutPutStream:OutputStream = mmSocket.outputStream
private val mmBuffer:ByteArray = ByteArray(1024)
val handler = Handler(Looper.getMainLooper())
override fun run() {
var numByte:Int //number of bytes returns from read()
//keep listen to the InputStream until an error occured
while (true){
//Read from inputStream
numByte = try {
mmInPutStream.read(mmBuffer)
}catch (e:IOException){
Log.e(TAG,"InputStream was disconnected",e)
break
}
//Send the message to Ui activity
val readMsg = handler.obtainMessage(
MESSAGE_READ,numByte,-1,mmBuffer
)
readMsg.sendToTarget()
}
}
//Call this function to mainActivity to send data to remote device
fun write(byte:ByteArray){
try {
mmOutPutStream.write(byte)
}catch (e:IOException){
Log.e(TAG,"Error occured during send messge",e)
//Send the failed message back to activity
val writeErrorMessage = handler.obtainMessage(MESSAGE_TOAST)
val bundle = Bundle().apply {
putString("Toast","could not send the data")
}
writeErrorMessage.data = bundle
handler.sendMessage(writeErrorMessage)
return
}
//Share the sent message with UI activity
val writtenMsg = handler.obtainMessage(
MESSAGE_WRITE, -1,-1,mmBuffer
)
writtenMsg.sendToTarget()
}
Then declare its on you class as below
class ZavodnikO : AppCompatActivity() {
var smer: Int = 50
private var send:SendReceive? = null
Then you should reassign the variable send on Class ConnectedThread as below
public override fun run() {
bluetoothAdapter?.cancelDiscovery()
mmSocket?.let { socket ->
Log.i("client", "Connecting")
socket!!.connect()
send = SendReceive(socket)
send!!.start()
}
Then you should be able to access the write() by call
send!!.write(byte)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
