Я пытаюсь написать приложение для Android, которое требует некоторых последовательных компаний с устройством Bluetooth. Некоторые из этих компаний - команда/ответ, а некоторые из них - это данные о событиях, которые просто отправляются с устройства. Все это упаковано с идентификаторами типа пакета. Я настраиваю последовательный резерв Bluetooth, который обрабатывает входные/выходные потоки BluetoothSocket. Я могу создать командные пакеты и отправить их. Поток принимает обработчик в качестве аргумента и отправляет сообщения в основной поток, когда получен полный пакет данных (горстка байтов в байторе). < /P>
Этот обработчик определяется в «обратном потоке», который переопределяет функцию «Handlemesse» и использует «Trysend», чтобы получить «Полученный пакет». В реальном времени в композиционном пользовательском интерфейсе в качестве шестигранного потока путем преобразования потока в Sharedflow в моем «данных Bluetooth Device» в Stateflow в моем ViewModel. UI. < /P>
Я думал, что смогу достичь этого, создав функции приостановки, которые можно назвать последовательно для выполнения ряда операций на внешнем устройстве. Например: < /p>
Send command 1
Wait for response
Send command 2
Wait for response
etc.
< /code>
Я пытаюсь понять, как они должны быть реализованы. Я в основном хочу инициировать отправку команды, а затем «прослушать» по потоку полученного пакета для правильного типа пакета, затем вернуть пакет из подвесной функции. /> fun btInputStreamHandler(): Flow = callbackFlow {
val btMessageHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
val b = msg.data
val rxpacket = b.getByteArray("rxpacket")
if (rxpacket != null) {
//handleRxPacket(rxpacket)
trySend(rxpacket)
}
}
}
//this messageHandler is passed into the serial comms thread when a new device is connected
messageHandler = btMessageHandler
awaitClose {
messageHandler = null
}
}
val btInputPacketSharedFlow: SharedFlow = btInputStreamHandler()
.shareIn(CoroutineScope(Dispatchers.IO), SharingStarted.Eagerly)
< /code>
В первую очередь я пытаюсь получить что-то подобное: < /p>
suspend fun getValueFromBluetoothDevice(): ByteArray {
//this is the serial comms thread that loads packets to be sent asynchronously
btSerialProcess?.sendCommand(DeviceCommand.getParameter1())
var flag: Boolean = true
var result: ByteArray = ByteArray(0)
while( flag ) {
//Wait for flow to emit the correct packet type
result = btInputPacketSharedFlow
.filterNotNull()
.first()
if( DeviceCommand.getPacketType(result) == CORRECT_PACKET_TYPE ) {
flag = false
}
}
return result
}
Очевидно, что здесь есть некоторые пробелы, потому что, хотя команда действительно отправляется, и ответ действительно возвращает (обновления пользовательского интерфейса со строкой пакета), функция приостановки не возвращает значение и даже не возвращается. class = "Lang-Kotlin PrettyPrint-Override">suspend fun getCmdResult(cmd: DeviceCommand, packetType1: Int, packetType2: Int): ByteArray {
var result: ByteArray = ByteArray(0)
var flag: Boolean = true
val job = CoroutineScope(Dispatchers.IO).launch {
btInputPacketSharedFlow.collect { packet ->
result = packet
if (
(DeviceCommand.getPacketType1(result) == packetType1)
and
(DeviceCommand.getPacketType2(result) == packetType2)
){
flag = false
}
}
}
btSerialProcess?.sendCommand(cmd)
while( flag ) {
delay(50)
}
job.cancel()
return result
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... ctions-and
Serial Comms Android с использованием потока, обработчика, потоков котлина, подвесных функций и составления ⇐ Android
Форум для тех, кто программирует под Android
1752857597
Anonymous
Я пытаюсь написать приложение для Android, которое требует некоторых последовательных компаний с устройством Bluetooth. Некоторые из этих компаний - команда/ответ, а некоторые из них - это данные о событиях, которые просто отправляются с устройства. Все это упаковано с идентификаторами типа пакета. Я настраиваю последовательный резерв Bluetooth, который обрабатывает входные/выходные потоки BluetoothSocket. Я могу создать командные пакеты и отправить их. Поток принимает обработчик в качестве аргумента и отправляет сообщения в основной поток, когда получен полный пакет данных (горстка байтов в байторе). < /P>
Этот обработчик определяется в «обратном потоке», который переопределяет функцию «Handlemesse» и использует «Trysend», чтобы получить «Полученный пакет». В реальном времени в композиционном пользовательском интерфейсе в качестве шестигранного потока путем преобразования потока в Sharedflow в моем «данных Bluetooth Device» в Stateflow в моем ViewModel. UI. < /P>
Я думал, что смогу достичь этого, создав функции приостановки, которые можно назвать последовательно для выполнения ряда операций на внешнем устройстве. Например: < /p>
Send command 1
Wait for response
Send command 2
Wait for response
etc.
< /code>
Я пытаюсь понять, как они должны быть реализованы. Я в основном хочу инициировать отправку команды, а затем «прослушать» по потоку полученного пакета для правильного типа пакета, затем вернуть пакет из подвесной функции. /> fun btInputStreamHandler(): Flow = callbackFlow {
val btMessageHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
val b = msg.data
val rxpacket = b.getByteArray("rxpacket")
if (rxpacket != null) {
//handleRxPacket(rxpacket)
trySend(rxpacket)
}
}
}
//this messageHandler is passed into the serial comms thread when a new device is connected
messageHandler = btMessageHandler
awaitClose {
messageHandler = null
}
}
val btInputPacketSharedFlow: SharedFlow = btInputStreamHandler()
.shareIn(CoroutineScope(Dispatchers.IO), SharingStarted.Eagerly)
< /code>
В первую очередь я пытаюсь получить что-то подобное: < /p>
suspend fun getValueFromBluetoothDevice(): ByteArray {
//this is the serial comms thread that loads packets to be sent asynchronously
btSerialProcess?.sendCommand(DeviceCommand.getParameter1())
var flag: Boolean = true
var result: ByteArray = ByteArray(0)
while( flag ) {
//Wait for flow to emit the correct packet type
result = btInputPacketSharedFlow
.filterNotNull()
.first()
if( DeviceCommand.getPacketType(result) == CORRECT_PACKET_TYPE ) {
flag = false
}
}
return result
}
Очевидно, что здесь есть некоторые пробелы, потому что, хотя команда действительно отправляется, и ответ действительно возвращает (обновления пользовательского интерфейса со строкой пакета), функция приостановки не возвращает значение и даже не возвращается. class = "Lang-Kotlin PrettyPrint-Override">suspend fun getCmdResult(cmd: DeviceCommand, packetType1: Int, packetType2: Int): ByteArray {
var result: ByteArray = ByteArray(0)
var flag: Boolean = true
val job = CoroutineScope(Dispatchers.IO).launch {
btInputPacketSharedFlow.collect { packet ->
result = packet
if (
(DeviceCommand.getPacketType1(result) == packetType1)
and
(DeviceCommand.getPacketType2(result) == packetType2)
){
flag = false
}
}
}
btSerialProcess?.sendCommand(cmd)
while( flag ) {
delay(50)
}
job.cancel()
return result
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79277567/android-serial-comms-using-thread-handler-kotlin-flows-suspend-functions-and[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия