#flutter #bluetooth #flutter-layout
#флаттер #bluetooth #флаттер-макет
Вопрос:
Я работаю над проектом, который заключается в установлении соединения между Flutter и ESP32 через Bluetooth. Я работаю со следующей библиотекой Bluetooth: flutter_bluetooth_serial: ^ 0.2.2. Я мог бы заставить все соединения и поиск работать с Bluetooth, но когда я пытаюсь ввести что-то с терминала ESP32 в приложение, это не работает, но отправка информации в ESP32 работает.
Вот как я получаю входящее сообщение:
@override
void initState() {
super.initState();
BluetoothConnection.toAddress(widget.server.address).then((_connection) {
print('Connected to the device');
connection = _connection;
setState(() {
isConnecting = false;
isDisconnecting = false;
});
connection.input.listen(_onDataReceived).onDone(() {
// Example: Detect which side closed the connection
// There should be `isDisconnecting` flag to show are we are (locally)
// in middle of disconnecting process, should be set before calling
// `dispose`, `finish` or `close`, which all causes to disconnect.
// If we except the disconnection, `onDone` should be fired as result.
// If we didn't except this (no flag set), it means closing by remote.
if (isDisconnecting) {
print('Disconnecting locally!');
} else {
print('Disconnected remotely!');
}
if (this.mounted) {
setState(() {});
}
});
}).catchError((error) {
print('Cannot connect, exception occured');
print(error);
});
}
void _onDataReceived(Uint8List data) {
// Allocate buffer for parsed data
int backspacesCounter = 0;
data.forEach((byte) {
if (byte == 8 || byte == 127) {
backspacesCounter ;
}
});
Uint8List buffer = Uint8List(data.length - backspacesCounter);
int bufferIndex = buffer.length;
print("Buffer" bufferIndex.toString());
// Apply backspace control character
backspacesCounter = 0;
for (int i = data.length - 1; i >= 0; i--) {
if (data[i] == 8 || data[i] == 127) {
backspacesCounter ;
} else {
if (backspacesCounter > 0) {
backspacesCounter--;
} else {
buffer[--bufferIndex] = data[i];
}
}
}
print(buffer);
// Create message if there is new line character
String dataString = String.fromCharCodes(buffer);
int index = buffer.indexOf(13);
if (~index != 0) {
setState(() {
messages.add(
_Message(
1,
backspacesCounter > 0
? _messageBuffer.substring(
0, _messageBuffer.length - backspacesCounter)
: _messageBuffer dataString.substring(0, index),
),
);
_messageBuffer = dataString.substring(index);
});
} else {
_messageBuffer = (backspacesCounter > 0
? _messageBuffer.substring(
0, _messageBuffer.length - backspacesCounter)
: _messageBuffer dataString);
}
}
Виджет построен таким образом:
@override
Widget build(BuildContext context) {
final List<Row> list = messages.map((_message) {
return Row(
children: <Widget>[
Container(
child: Text(
(text) {
return text == '/shrug' ? '¯\_(ツ)_/¯' : text;
}(_message.text.trim()),
style: TextStyle(color: Colors.white)),
padding: EdgeInsets.all(12.0),
margin: EdgeInsets.only(bottom: 8.0, left: 8.0, right: 8.0),
width: 222.0,
decoration: BoxDecoration(
color:
_message.whom == clientID ? Colors.blueAccent : Colors.grey,
borderRadius: BorderRadius.circular(7.0)),
),
],
mainAxisAlignment: _message.whom == clientID
? MainAxisAlignment.end
: MainAxisAlignment.start,
);
}).toList();
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: (isConnecting
? Text('Connecting chat to ' widget.server.name '...')
: isConnected
? Text('Chating: ' widget.server.name)
: Text('Chat log: ' widget.server.name))
),
body: SafeArea(
child: Column(
children: <Widget>[
SizedBox(height: 10,),
Flexible(
child: ListView(
padding: const EdgeInsets.all(12.0),
controller: listScrollController,
children: list),
),
Row(
children: <Widget>[
Flexible(
child: Container(
color: Colors.white12,
margin: const EdgeInsets.only(left: 16.0),
child: TextField(
style: const TextStyle(fontSize: 15.0),
controller: textEditingController,
decoration: InputDecoration.collapsed(
hintText: isConnecting
? 'Wait until connected...'
: isConnected
? 'Type your message...'
: 'Chat got disconnected',
hintStyle: const TextStyle(color: Colors.grey),
),
enabled: isConnected,
),
),
),
Container(
margin: const EdgeInsets.all(8.0),
child: IconButton(
icon: const Icon(Icons.send),
onPressed: isConnected
? () => _sendMessage(textEditingController.text)
: null),
),
],
)
],
),
),
);
}
Ответ №1:
Я столкнулся с той же проблемой. Во-первых, всегда старайтесь добавлять журналы, чтобы узнать, действительно ли ваш телефон получает сообщения. Я сделал это, и мое приложение получало сообщения. Проблема в строке:
buffer.indexOf(13);
Где ASCII для 13 — это ENTER, и ваше сообщение, вероятно, отправляет ASCII для n, что равно 10. Попробуйте изменить на:
buffer.indexOf(10);
Ответ №2:
На всякий случай, если у кого-то возникли проблемы с этой аналогичной проблемой, но он не может фактически получить данные: если у вас уже есть эта строка
connection.input.listen(null).onDone(()
вам не нужно добавлять другую аналогичную логику для регистрации функции обратного вызова «_onDataReceived»; вместо этого вам следует только заменить «null» в объявлении listen().