Reputation: 73
I am using flutter_blue
package for using the Bluetooth service. I want to check whether the device has Bluetooth capabilities. The method isAvailable
seems to do it. However, it returns a Future<bool>, which I am tryting to get into a variable as follows:
import 'package:flutter_blue/flutter_blue.dart';
class BT_Base {
final FlutterBlue _fb = FlutterBlue.instance;
bool BTAvailable = true; // as a default placeholder
BT_Base () {
BTAvailable = _fixAvail();
}
_fixAvail () async {
return await _fb.isAvailable;
}
...
I try to get the future value from it and store into BTAvailable
. Later on, I use the fixed BTAvailable
field to get the appropriate Widget to be passed onto as follows:
class BTDevicePrompt extends StatelessWidget {
@override
Widget build(BuildContext context) {
BT_Base bt = BT_Base();
var btDeviceRes = bt.scan();
if(!bt.BTAvailable) return Text('Bluetooth unavailable on device...');
else if (btDeviceRes.isEmpty) return Text('No Bluetooth devices in range...');
else {
return CupertinoActionSheet(
actions: [
...
],
)
}
}
}
But I keep getting the error type 'Future<dynamic>' is not a subtype of type 'bool'
at runtime. How can I use the Future properly in this situation? It is alright if the whole process just halts and waits for this part as well.
I have gone through a lot of solutions but I am not able to piece it together.
Upvotes: 2
Views: 4078
Reputation: 10156
Any method marked async
always returns a Future
of some kind. You can give it an explicit return type like Future<bool> function() async { ... }
, or if you leave it out it will infer Future<dynamic>
.
In short, you can't get a bool
from a Future<bool>
outside of an async
function (there are technically ways but almost certainly not what you want in Flutter).
This makes sense, since the whole point of a Future<bool>
is that it's going to be a bool
in the future. If there was some process to convert from a Future<bool>
to a bool
, what should it do if the future has not yet completed? Perhaps it should wait until it has completed. In that case, you're just describing the await
keyword.
If, however, you want to use a Future
in your UI in a Flutter application, you have a few options.
The simplest for your case will be to move it into initState()
:
class BTDevicePrompt extends StatefulWidget {
// stateful widget boilerplate
}
class BTDevicePromptState extends State<BTDevicePrompt> {
bool isAvailable = false;
@override
void initState() {
super.initState();
checkAvailable(); // use a helper method because initState() cannot be async
}
Future<void> checkAvailable() async {
// call an async function and wait for it to complete
bool result = await checkIfBluetoothAvailable();
setState(() => bluetoothAvailable = result); // set the local variable
}
@override
Widget build(BuildContext context) {
if (bluetoothAvailable) return Text('bluetooth available');
else return Text('bluetooth not available');
}
}
Upvotes: 5