Skip to content

Commit

Permalink
3.0.2 (#21)
Browse files Browse the repository at this point in the history
* fix: 优化界面

* fix: 修复已知问题

* fix: 代码优化

* fix: 修复已知问题

* fix: 优化 getMaximumWriteLength 方法

* fix: 修改版本号

* fix: 修改版本号

* fix: 修改 CHANGELOG
  • Loading branch information
iAMD authored Oct 18, 2023
1 parent 4bec1c9 commit 728402a
Show file tree
Hide file tree
Showing 26 changed files with 859 additions and 400 deletions.
14 changes: 10 additions & 4 deletions bluetooth_low_energy/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
## 3.0.2

* `Android` `iOS` Fix the issue that `getMaximumWriteLength` is wrong and coerce the value from 20 to 512.
* `Android` `iOS` Fix the issue that the peripheral manager response is wrong.
* `Android` Request MTU with 517 automatically.

## 3.0.1

* [Android] Clear cache when disconnected.
* [Android] Fix GATT server error aftter bluetooth reopened.
* [iOS] Fix the issue that write characteristic will never complete when write without response.
* [iOS] Fix the issue that write characteristic will never complete after disconnected.
* `Android` Clear cache when disconnected.
* `Android` Fix GATT server error aftter bluetooth reopened.
* `iOS` Fix the issue that write characteristic will never complete when write without response.
* `iOS` Fix the issue that write characteristic will never complete after disconnected.

## 3.0.0

Expand Down
4 changes: 1 addition & 3 deletions bluetooth_low_energy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ Remember to call `await CentralController.setUp()` before use any apis of this p

Make sure you have a `miniSdkVersion` with 21 or higher in your `android/app/build.gradle` file.

*Note:* Don't call `getMaximumWriteLength` immediately when connected to a peripheral after Android 13, the `onMtuChanged` callback maybe called with connection events after Android 13, and `getMaximumWriteLength` will call `requestMtu` will also triggered `onMtuChanged`, if you called this before the connection `onMtuChanged`, you will get a fake completion and cause all methods you called before the real `onMtuChanged` triggered will never complete!

### iOS and macOS

According to Apple's [documents](https://developer.apple.com/documentation/corebluetooth/), you must include the [`NSBluetoothAlwaysUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothalwaysusagedescription) on or after iOS 13, and include the [`NSBluetoothPeripheralUsageDescription`](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothperipheralusagedescription) key before iOS 13.

The `PeripheralManager#startAdvertising` only support `name` and `serviceUUIDs`, see [the startAdvertising document](https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising)
*Note:* The `PeripheralManager#startAdvertising` only support `name` and `serviceUUIDs`, see [the startAdvertising document](https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising)

### Linux

Expand Down
175 changes: 116 additions & 59 deletions bluetooth_low_energy/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class _ScannerViewState extends State<ScannerView> {
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
trailing: Text('$rssi'),
trailing: RssiWidget(rssi),
);
},
separatorBuilder: (context, i) {
Expand Down Expand Up @@ -375,10 +375,13 @@ class _PeripheralViewState extends State<PeripheralView> {
late final ValueNotifier<GattCharacteristic?> characteristic;
late final ValueNotifier<GattCharacteristicWriteType> writeType;
late final ValueNotifier<int> maximumWriteLength;
late final ValueNotifier<int> rssi;
late final ValueNotifier<List<Log>> logs;
late final TextEditingController writeController;
late final StreamSubscription stateChangedSubscription;
late final StreamSubscription valueChangedSubscription;
late final StreamSubscription rssiChangedSubscription;
late final Timer rssiTimer;

@override
void initState() {
Expand All @@ -390,7 +393,8 @@ class _PeripheralViewState extends State<PeripheralView> {
service = ValueNotifier(null);
characteristic = ValueNotifier(null);
writeType = ValueNotifier(GattCharacteristicWriteType.withResponse);
maximumWriteLength = ValueNotifier(20);
maximumWriteLength = ValueNotifier(0);
rssi = ValueNotifier(-100);
logs = ValueNotifier([]);
writeController = TextEditingController();
stateChangedSubscription = centralManager.peripheralStateChanged.listen(
Expand Down Expand Up @@ -423,6 +427,17 @@ class _PeripheralViewState extends State<PeripheralView> {
];
},
);
rssiTimer = Timer.periodic(
const Duration(seconds: 1),
(timer) async {
final state = this.state.value;
if (state) {
rssi.value = await centralManager.readRSSI(eventArgs.peripheral);
} else {
rssi.value = -100;
}
},
);
}

@override
Expand Down Expand Up @@ -455,10 +470,18 @@ class _PeripheralViewState extends State<PeripheralView> {
final peripheral = eventArgs.peripheral;
if (state) {
await centralManager.disconnect(peripheral);
maximumWriteLength.value = 0;
rssi.value = 0;
} else {
await centralManager.connect(peripheral);
services.value =
await centralManager.discoverGATT(peripheral);
maximumWriteLength.value =
await centralManager.getMaximumWriteLength(
peripheral,
type: writeType.value,
);
rssi.value = await centralManager.readRSSI(peripheral);
}
},
child: Text(state ? 'DISCONNECT' : 'CONNECT'),
Expand Down Expand Up @@ -592,72 +615,82 @@ class _PeripheralViewState extends State<PeripheralView> {
),
Row(
children: [
Expanded(
child: Center(
child: ValueListenableBuilder(
valueListenable: writeType,
builder: (context, writeType, child) {
final items =
GattCharacteristicWriteType.values.map((type) {
return DropdownMenuItem(
value: type,
child: Text(
type.name,
style: theme.textTheme.bodyMedium,
),
);
}).toList();
return DropdownButton(
items: items,
onChanged: (type) {
if (type == null) {
return;
}
this.writeType.value = type;
},
value: writeType,
underline: const Offstage(),
ValueListenableBuilder(
valueListenable: writeType,
builder: (context, writeType, child) {
return ToggleButtons(
onPressed: (i) async {
final type = GattCharacteristicWriteType.values[i];
this.writeType.value = type;
maximumWriteLength.value =
await centralManager.getMaximumWriteLength(
eventArgs.peripheral,
type: type,
);
},
),
),
constraints: const BoxConstraints(
minWidth: 0.0,
minHeight: 0.0,
),
borderRadius: BorderRadius.circular(4.0),
isSelected: GattCharacteristicWriteType.values
.map((type) => type == writeType)
.toList(),
children: GattCharacteristicWriteType.values.map((type) {
return Container(
margin: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 4.0,
),
child: Text(type.name),
);
}).toList(),
);
// final segments =
// GattCharacteristicWriteType.values.map((type) {
// return ButtonSegment(
// value: type,
// label: Text(type.name),
// );
// }).toList();
// return SegmentedButton(
// segments: segments,
// selected: {writeType},
// showSelectedIcon: false,
// style: OutlinedButton.styleFrom(
// tapTargetSize: MaterialTapTargetSize.shrinkWrap,
// padding: EdgeInsets.zero,
// visualDensity: VisualDensity.compact,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8.0),
// ),
// ),
// );
},
),
Expanded(
child: ValueListenableBuilder(
valueListenable: state,
builder: (context, state, child) {
return TextButton(
onPressed: state
? () async {
maximumWriteLength.value =
await centralManager.getMaximumWriteLength(
eventArgs.peripheral,
type: writeType.value,
);
}
: null,
child: ValueListenableBuilder(
valueListenable: maximumWriteLength,
builder: (context, maximumWriteLength, child) {
return Text('MTU: $maximumWriteLength');
},
),
);
},
),
const SizedBox(width: 8.0),
ValueListenableBuilder(
valueListenable: state,
builder: (context, state, child) {
return ValueListenableBuilder(
valueListenable: maximumWriteLength,
builder: (context, maximumWriteLength, child) {
return Text('$maximumWriteLength');
},
);
},
),
IconButton(
onPressed: () async {
final rssi =
await centralManager.readRSSI(eventArgs.peripheral);
log('RSSI: $rssi');
const Spacer(),
ValueListenableBuilder(
valueListenable: rssi,
builder: (context, rssi, child) {
return RssiWidget(rssi);
},
icon: const Icon(Icons.signal_wifi_4_bar),
),
],
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16.0),
margin: const EdgeInsets.only(bottom: 16.0),
height: 160.0,
child: ValueListenableBuilder(
valueListenable: characteristic,
Expand Down Expand Up @@ -755,6 +788,7 @@ class _PeripheralViewState extends State<PeripheralView> {
@override
void dispose() {
super.dispose();
rssiTimer.cancel();
stateChangedSubscription.cancel();
valueChangedSubscription.cancel();
state.dispose();
Expand All @@ -764,6 +798,7 @@ class _PeripheralViewState extends State<PeripheralView> {
characteristic.dispose();
writeType.dispose();
maximumWriteLength.dispose();
rssi.dispose();
logs.dispose();
writeController.dispose();
}
Expand Down Expand Up @@ -1070,3 +1105,25 @@ enum LogType {
notify,
error,
}

class RssiWidget extends StatelessWidget {
final int rssi;

const RssiWidget(
this.rssi, {
super.key,
});

@override
Widget build(BuildContext context) {
final IconData icon;
if (rssi > -70) {
icon = Icons.wifi_rounded;
} else if (rssi > -100) {
icon = Icons.wifi_2_bar_rounded;
} else {
icon = Icons.wifi_1_bar_rounded;
}
return Icon(icon);
}
}
10 changes: 5 additions & 5 deletions bluetooth_low_energy/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ packages:
path: ".."
relative: true
source: path
version: "3.0.1"
version: "3.0.2"
bluetooth_low_energy_android:
dependency: transitive
description:
name: bluetooth_low_energy_android
sha256: "54fbbc1ce1a25ae20692a71585e551f1d5e2d565f41c6f9dce13457f00e9bae8"
sha256: "0fa5c4625ac01b6d4bbf78b10d0389d8e9907ae7c3fbc9601b481ddd4eaa86b6"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.3"
bluetooth_low_energy_darwin:
dependency: transitive
description:
name: bluetooth_low_energy_darwin
sha256: "114e492a020ac1efaa3b169eba8b6c01f50f97f2bbcda2f1fff890a5abf353ae"
sha256: "797d3803de3b124ffb13267910f8d727ae4884fdcc621ccc0995076107468bb6"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
bluetooth_low_energy_linux:
dependency: transitive
description:
Expand Down
6 changes: 3 additions & 3 deletions bluetooth_low_energy/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: bluetooth_low_energy
description: A Flutter plugin for controlling the bluetooth low energy.
version: 3.0.1
version: 3.0.2
homepage: https://github.com/yanshouwang/bluetooth_low_energy

environment:
Expand All @@ -11,8 +11,8 @@ dependencies:
flutter:
sdk: flutter
bluetooth_low_energy_platform_interface: ^3.0.0
bluetooth_low_energy_android: ^3.0.1
bluetooth_low_energy_darwin: ^3.0.1
bluetooth_low_energy_android: ^3.0.3
bluetooth_low_energy_darwin: ^3.0.2
bluetooth_low_energy_linux: ^3.0.0

dev_dependencies:
Expand Down
10 changes: 10 additions & 0 deletions bluetooth_low_energy_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 3.0.3

* Fix the issue that `getMaximumWriteLength` is wrong and coerce the value from 20 to 512.

## 3.0.2

* Request MTU with 517 automatically.
* Fix the issue taht `CentralManager#getMaximumWriteLength` is wrong when write with response and coerce the value from 20 to 512.
* Fix the issue that the GATT server response is wrong.

## 3.0.1

* Clear cache when disconnected.
Expand Down
Loading

0 comments on commit 728402a

Please sign in to comment.