When running the following sample code from Flutter Blue's pub page to scan for nearby devices, the list returns as empty on my Android device. When going to settings I see the name of my BLE device.
The code is:
FlutterBlue flutterBlue = FlutterBlue.instance;
flutterBlue.startScan(timeout: Duration(seconds: 4));
var subscription = flutterBlue.scanResults.listen((results) {
// this code is run almost immediately rather than after a 4 second timeout.
for (ScanResult r in results) {
print('${r.device.name} found! rssi: ${r.rssi}');
}
});
//Ive tried with and without the following line
flutterBlue.stopScan();
Bluetooth and location permissions are enabled on the app.
What are some things that could be causing this?
Related
This code works on real phones but not on emulators
I use flutter_facebook_auth. This exact code worked fine before emulator update and it's still works on real devices, but on emulator it just do nothing after coming back from fb login page.
static Future<User?> signInWithFacebook() async {
try {
//Trigger the sign-in flow
final LoginResult loginResult =
await FacebookAuth.instance.login(permissions: [
'public_profile',
'email',
'user_friends',
]);
if (loginResult.status == LoginStatus.success) {
print('success');
facebookAuthCredential =
FacebookAuthProvider.credential(loginResult.accessToken!.token);
print(loginResult.accessToken?.token);
Credential = await FirebaseAuth.instance
.signInWithCredential(facebookAuthCredential);
print('here 1');
UserData = await FacebookAuth.instance.getUserData(
fields:
"name,email,picture.width(400),birthday,friends,gender,link");
print(UserData);
} else {
print(loginResult.message);
error = loginResult.message!;
}
user = Credential.user;
await user
?.updatePhotoURL(UserData['picture']['data']['url'])
.then((value) {
print('success' + UserData['picture']['data']['url']);
});
return Credential.user;
} on FirebaseException catch (e) {
error = e.code;
print(e.code);
}
}
}
In the above code the app flow stops or freezes on
Credential = await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
What I have tried is:
Tried other emulators, different api's and models.
I tried adding new release and debug keyhashes to both facebook and firebase
I tried increasing emulator ram and cpu cores etc
I tried refreshing fb sdk and json and other dev dependencies
I tried flutter clean
I tried Invalidate Caches
I uninstalled android studio and all of it's components and install again
Is this happening with just me or it's a bug in the new emulator update?
It's been 12 hours, can somebody please help and check if their updated emulator is working with fb login
I solved it by downgrading emulator version to 31.2.9,
Here is emulator_archive how you can do it:
I need to send a file .txt from a device to my app (worst case almost 2mb). The BLE device divide the file into packages. I don't know if my method is correct, but I create a loop of characteristic.write/characteristic.read telling everytime what package the device has to send.
Here's my code:
for(int i = 0; i < packNumber.length; i++) {
initialValue = '9,50,100,$i,0,$checksumId,0/';
await characteristic
.write(utf8.encode(initialValue)).then((wValue) async {
await Future.delayed(Duration(milliseconds: 100)).then((value) async {
await characteristic.read().then((rValue) {
//do something with rVlaue
});
});
});
}
It works, but is it the best solution? And in case how can I speed up the transfer (for now I have to set a delay before reading, waiting for characteristic.write to finish)?
Thank you guys
You should change the remote device to send notifications instead of using reads. That gives maximum throughput.
How to get the name of a connected device in flutter?
I need only the name of the device connected to the smartphone ie: "Toyota car"
P.S. For Andorid if it makes some difference
Could use flutter_blue package
In the example it's shown how to get device name.
Or could simply:
// Start scanning
flutterBlue.startScan(timeout: Duration(seconds: 4));
// Listen to scan results
var subscription = flutterBlue.scanResults.listen((results) {
// do something with scan results
for (ScanResult r in results) {
print('${r.device.name} found! rssi: ${r.rssi}');
}
});
// Stop scanning
flutterBlue.stopScan();
I have this problem is that in flutter I notice there is not able to operate or use the traditional bluetooth as there is no any library supporting it. I have tested flutter_blue-master etc. So then I saw that it can behave as beacon. So I have used the codes below. For android I just set
Region(
identifier: 'com.example.myDeviceRegion',)); its able to work. So the same I set in IOS its not able to work? So what is best workaround for blueetooth in flutter? I am using this package flutter_beacon. For the beacon broadcasting I am using this package beacon_broadcast.
initScanBeacon() async {
await flutterBeacon.initializeScanning;
await checkAllRequirements();
if (!authorizationStatusOk ||
!locationServiceEnabled ||
!bluetoothEnabled) {
print('RETURNED, authorizationStatusOk=$authorizationStatusOk, '
'locationServiceEnabled=$locationServiceEnabled, '
'bluetoothEnabled=$bluetoothEnabled');
return;
}
/*final regions = <Region>[
Region(
identifier: 'com.example.myDeviceRegion',
),
];*/
final regions = <Region>[];
regions.add(Region(
identifier: 'com.example.myDeviceRegion',
minor: 100,
major: 1));
if (_streamRanging != null) {
if (_streamRanging.isPaused) {
_streamRanging.resume();
return;
}
}
_streamRanging =
flutterBeacon.monitoring(regions).listen((MonitoringResult result) {
print(result);
if (result != null && mounted) {
print("GOT RESTULT READY");
setState(() {
//_regionBeacons[result.region] = result.region;
_beacons.clear();
print("List value is json"+result.toJson.toString());
_regionBeacons.values.forEach((list) {
print("List value is");
_beacons.addAll(list);
print("after Beacon size now is "+_beacons.length.toString());
});
//_beacons.sort(_compareParameters);
print("Beacon size now is "+_beacons.length.toString());
});
}
});
}
A few things to check:
Make sure your Region definition has a proximityUUID value. I am surprised that it works even on Android without this. On iOS it certainly won't work at all -- iOS requires a beacon proximityUUID be specified up front in order to detect. The value you give for the prximityUUID must exactly match what your beacon is advertising or you won't see it.
Make sure you have gone through all the iOS setup steps here: https://pub.dev/packages/flutter_beacon
Be extra sure that you have granted location permission to your iOS app. You can go to Settings -> Your App Name to check if location permission is granted.
Make sure bluetooth is enabled in settings for the phone
Make sure location is enabled in settings for the phone
https://pub.dev/packages/flutter_beacon
There's an update on GitHub but was yet to push to pub.dev previously.
Do update to 0.5.0.
Always check pub.dev for updates. or github reported issues.
Is there any way to check if my device supports BLE through dart code? I am looking for something like this.
switch ([_manager state])
{
case CBCentralManagerStateUnsupported:
state = #"This device does not support Bluetooth Low Energy.";
break;
case CBCentralManagerStateUnauthorized:
state = #"This app is not authorized to use Bluetooth Low Energy.";
break;
case CBCentralManagerStatePoweredOff:
state = #"Bluetooth on this device is currently powered off.";
break;
case CBCentralManagerStateResetting:
state = #"The BLE Manager is resetting; a state update is pending.";
break;
case CBCentralManagerStatePoweredOn:
state = #"Bluetooth LE is turned on and ready for communication.";
break;
case CBCentralManagerStateUnknown:
state = #"The state of the BLE Manager is unknown.";
break;
default:
state = #"The state of the BLE Manager is unknown.";
}
I know this is an old thread, Thought of updating this anyway as it might help someone else.
You can try using FlutterBlue bluetooth plugin, which is a new SDK from Flutter.
FlutterBlue aims to offer the most from both platforms (iOS and Android).
FlutterBlue should work for both Android and IOS platform. The plugin should also help to scan and connect nearby devices.
Here is the sample from the documentation:
[https://github.com/pauldemarco/flutter_blue#obtain-an-instance][1]
Obtain an instance:
FlutterBlue flutterBlue = FlutterBlue.instance;
isAvailable property checks if whether the device supports Bluetooth
Future<bool> get isAvailable =>
_channel.invokeMethod('isAvailable').then<bool>((d) => d);
isOn property Checks if Bluetooth functionality is turned on :
Future<bool> get isOn => _channel.invokeMethod('isOn').then<bool>((d) => d);
Scan for devices :[https://github.com/pauldemarco/flutter_blue#scan-for-devices][2]
// Start scanning
flutterBlue.startScan(timeout: Duration(seconds: 4));
// Listen to scan results
var subscription = flutterBlue.scanResults.listen((scanResult) {
// do something with scan result
device = scanResult.device;
print('${device.name} found! rssi: ${scanResult.rssi}');
});
// Stop scanning
flutterBlue.stopScan();
Connect/disconnect to a device
https://github.com/pauldemarco/flutter_blue#connect-to-a-device
// Connect to the device
await device.connect();
// Disconnect from device
device.disconnect();
Discover services:
https://github.com/pauldemarco/flutter_blue#discover-services
List<BluetoothService> services = await device.discoverServices();
services.forEach((service) {
// do something with service
});
You can scan for low energy devices with ScanMode.lowLatency :
Stream<ScanResult> scan({
ScanMode scanMode = ScanMode.lowLatency,
List<Guid> withServices = const [],
List<Guid> withDevices = const [],
Duration timeout,
}) async* {
var settings = protos.ScanSettings.create()
..androidScanMode = scanMode.value
..serviceUuids.addAll(withServices.map((g) => g.toString()).toList());
if (_isScanning.value == true) {
throw Exception('Another scan is already in progress.');
}
....
You can also read, write the characters and discriptors or do other stuff with the help of FlutterBlue. Hope that helps.
[1]: https://github.com/pauldemarco/flutter_blue#obtain-an-instance
[2]: https://github.com/pauldemarco/flutter_blue#scan-for-devices