如何从 flutter_reactive_ble 示例中获取设备服务
How to get deviceServices from flutter_reactive_ble example
我正在使用 flutter_reactive_ble 项目 (https://github.com/PhilipsHue/flutter_reactive_ble) 中提供的示例,特别是在 device_detail_screen.dart 文件中.
我认为它应该有效,但我想知道如何将 discoverServices(device.id) 的结果保存为变量,这样我就可以在文本小部件或其他东西中显示它(至少这是计划)。每次我尝试这样做时,我都会收到一条错误消息:This expression has a type of 'void' so its value can't be used.
我认为这是因为它是 Future> 类型(声明见下文)
Future<List< DiscoveredService>> discoverServices (String deviceId)
我对此很陌生,所以我只是想弄清楚这一切是如何工作的。
每当我单击“发现服务”按钮时,所有服务都会显示在我的计算机终端中,但我希望它们最终显示在设备上。
如果您不想查看整个项目,请查看实际代码。我很确定这是适用的文件。我在要查询的行上加上了“***”。
如果您需要更多信息或说明,请告诉我。谢谢!
import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:flutter_reactive_ble_example/src/ble/ble_device_connector.dart';
import 'package:provider/provider.dart';
class DeviceDetailScreen extends StatelessWidget {
final DiscoveredDevice device;
const DeviceDetailScreen({@required this.device}) : assert(device != null);
@override
Widget build(BuildContext context) =>
Consumer2<BleDeviceConnector, ConnectionStateUpdate>(
builder: (_, deviceConnector, connectionStateUpdate, __) =>
_DeviceDetail(
device: device,
connectionUpdate: connectionStateUpdate != null &&
connectionStateUpdate.deviceId == device.id
? connectionStateUpdate
: ConnectionStateUpdate(
deviceId: device.id,
connectionState: DeviceConnectionState.disconnected,
failure: null,
),
connect: deviceConnector.connect,
disconnect: deviceConnector.disconnect,
discoverServices: deviceConnector.discoverServices,
),
);
}
class _DeviceDetail extends StatelessWidget {
const _DeviceDetail({
@required this.device,
@required this.connectionUpdate,
@required this.connect,
@required this.disconnect,
@required this.discoverServices,
Key key,
}) : assert(device != null),
assert(connectionUpdate != null),
assert(connect != null),
assert(disconnect != null),
assert(discoverServices != null),
super(key: key);
final DiscoveredDevice device;
final ConnectionStateUpdate connectionUpdate;
final void Function(String deviceId) connect;
final void Function(String deviceId) disconnect;
final void Function(String deviceId) discoverServices;
bool _deviceConnected() =>
connectionUpdate.connectionState == DeviceConnectionState.connected;
@override
Widget build(BuildContext context) => WillPopScope(
onWillPop: () async {
disconnect(device.id);
return true;
},
child: Scaffold(
appBar: AppBar(
title: Text(device.name ?? "unknown"),
),
body: Center(
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"ID: ${connectionUpdate.deviceId}",
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Status: ${connectionUpdate.connectionState}",
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: !_deviceConnected()
? () => connect(device.id)
: null,
child: const Text("Connect"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: _deviceConnected()
? () => disconnect(device.id)
: null,
child: const Text("Disconnect"),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
// onPressed: _deviceConnected() // *** original code from example
// ? () => discoverServices(device.id) // *** original code from example
// : null, // *** original code from example
onPressed: (){
if (_deviceConnected()){ // *** My attempt at storing as a variable (this entire anonymous function)
var services = discoverServices(device.id);
print("services: $services"); // *** services is underlined with an error: This expression has a type of 'void' so its value can't be used.
}
},
child: const Text("Discover Services"),
),
),
],
),
Text("data"), // *** Where I'd like to populate the results of the discoverServices(device.id)
],
),
),
),
),
);
}
我希望你的 BleDeviceConnector
等于 this。
如果您想使用 FlutterReactiveBle::discoverServices(...) 中的值 List<DiscoveredService>
,您必须将 BleDeviceConnector::discoverServices(...)
函数修改为...
Future<List<DiscoveredService>> discoverServices(String deviceId) => _ble.discoverServices(deviceId);
你的 onPressed
回拨给...
onPressed: () async {
if (_deviceConnected()) {
var services = await discoverServices(device.id);
print("services: $services");
// TODO: Insert your code to update the UI of "Text("data"),"
}
},
编辑:
您还需要修改 _DeviceDetail
的 discoverServices
为...
final Future<List<DiscoveredService>> Function(String deviceId) discoverServices;
我正在使用 flutter_reactive_ble 项目 (https://github.com/PhilipsHue/flutter_reactive_ble) 中提供的示例,特别是在 device_detail_screen.dart 文件中.
我认为它应该有效,但我想知道如何将 discoverServices(device.id) 的结果保存为变量,这样我就可以在文本小部件或其他东西中显示它(至少这是计划)。每次我尝试这样做时,我都会收到一条错误消息:This expression has a type of 'void' so its value can't be used.
我认为这是因为它是 Future> 类型(声明见下文)
Future<List< DiscoveredService>> discoverServices (String deviceId)
我对此很陌生,所以我只是想弄清楚这一切是如何工作的。
每当我单击“发现服务”按钮时,所有服务都会显示在我的计算机终端中,但我希望它们最终显示在设备上。
如果您不想查看整个项目,请查看实际代码。我很确定这是适用的文件。我在要查询的行上加上了“***”。
如果您需要更多信息或说明,请告诉我。谢谢!
import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:flutter_reactive_ble_example/src/ble/ble_device_connector.dart';
import 'package:provider/provider.dart';
class DeviceDetailScreen extends StatelessWidget {
final DiscoveredDevice device;
const DeviceDetailScreen({@required this.device}) : assert(device != null);
@override
Widget build(BuildContext context) =>
Consumer2<BleDeviceConnector, ConnectionStateUpdate>(
builder: (_, deviceConnector, connectionStateUpdate, __) =>
_DeviceDetail(
device: device,
connectionUpdate: connectionStateUpdate != null &&
connectionStateUpdate.deviceId == device.id
? connectionStateUpdate
: ConnectionStateUpdate(
deviceId: device.id,
connectionState: DeviceConnectionState.disconnected,
failure: null,
),
connect: deviceConnector.connect,
disconnect: deviceConnector.disconnect,
discoverServices: deviceConnector.discoverServices,
),
);
}
class _DeviceDetail extends StatelessWidget {
const _DeviceDetail({
@required this.device,
@required this.connectionUpdate,
@required this.connect,
@required this.disconnect,
@required this.discoverServices,
Key key,
}) : assert(device != null),
assert(connectionUpdate != null),
assert(connect != null),
assert(disconnect != null),
assert(discoverServices != null),
super(key: key);
final DiscoveredDevice device;
final ConnectionStateUpdate connectionUpdate;
final void Function(String deviceId) connect;
final void Function(String deviceId) disconnect;
final void Function(String deviceId) discoverServices;
bool _deviceConnected() =>
connectionUpdate.connectionState == DeviceConnectionState.connected;
@override
Widget build(BuildContext context) => WillPopScope(
onWillPop: () async {
disconnect(device.id);
return true;
},
child: Scaffold(
appBar: AppBar(
title: Text(device.name ?? "unknown"),
),
body: Center(
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"ID: ${connectionUpdate.deviceId}",
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Status: ${connectionUpdate.connectionState}",
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: !_deviceConnected()
? () => connect(device.id)
: null,
child: const Text("Connect"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: _deviceConnected()
? () => disconnect(device.id)
: null,
child: const Text("Disconnect"),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
// onPressed: _deviceConnected() // *** original code from example
// ? () => discoverServices(device.id) // *** original code from example
// : null, // *** original code from example
onPressed: (){
if (_deviceConnected()){ // *** My attempt at storing as a variable (this entire anonymous function)
var services = discoverServices(device.id);
print("services: $services"); // *** services is underlined with an error: This expression has a type of 'void' so its value can't be used.
}
},
child: const Text("Discover Services"),
),
),
],
),
Text("data"), // *** Where I'd like to populate the results of the discoverServices(device.id)
],
),
),
),
),
);
}
我希望你的 BleDeviceConnector
等于 this。
如果您想使用 FlutterReactiveBle::discoverServices(...) 中的值 List<DiscoveredService>
,您必须将 BleDeviceConnector::discoverServices(...)
函数修改为...
Future<List<DiscoveredService>> discoverServices(String deviceId) => _ble.discoverServices(deviceId);
你的 onPressed
回拨给...
onPressed: () async {
if (_deviceConnected()) {
var services = await discoverServices(device.id);
print("services: $services");
// TODO: Insert your code to update the UI of "Text("data"),"
}
},
编辑:
您还需要修改 _DeviceDetail
的 discoverServices
为...
final Future<List<DiscoveredService>> Function(String deviceId) discoverServices;