Improve web (#3)

* Improve web example app

* Improve readme

* Minor improvements

* add github workflow for example app

* Fix flutter version in github action

* Fix flutter version in github action

* Fix flutter version in github action

* Fix flutter version in github action

* Minor fix

* Minor fixes

* Update readme and version

* Update Changelog

* Improve wording

* Update CHANGELOG.md

Co-authored-by: Foti Dim <foti@navideck.com>

---------

Co-authored-by: Foti Dim <fdimanidis@gmail.com>
Co-authored-by: Foti Dim <foti@navideck.com>
This commit is contained in:
Rohit Sangwan
2024-01-26 15:25:55 +05:30
committed by Foti Dim
parent 531b6139c4
commit 2326e598cf
7 changed files with 139 additions and 52 deletions
+37
View File
@@ -0,0 +1,37 @@
name: Build web app
on:
push:
branches: [ "main" ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.16.0'
channel: 'stable'
- run: flutter --version
- name: Cache pub dependencies
uses: actions/cache@v2
with:
path: ${{ env.FLUTTER_HOME }}/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: ${{ runner.os }}-pub-
- name: Download pub dependencies
run: flutter pub get
- name: Build Web App
run: cd example && flutter build web --base-href=/universal_ble/
- name: Deploy to GitHub Pages 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: example/build/web
+7 -1
View File
@@ -1,5 +1,11 @@
## 0.8.4
* Add `WebRequestOptionsBuilder.defaultServices` for convenience when setting `optionalServices` when scanning on web
* Add "try online" URL in readme
* Improve readme
* Improve example app
## 0.8.3
* Rename onPairStateChange -> onPairingStateChange
* Rename onPairStateChange *> onPairingStateChange
* Improve readme
## 0.8.2
+22 -15
View File
@@ -2,7 +2,9 @@
[![universal_ble version](https://img.shields.io/pub/v/universal_ble?label=universal_ble)](https://pub.dev/packages/universal_ble)
A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter
A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter.
[Try it online](https://navideck.github.io/universal_ble/), provided your browser supports [Web Bluetooth](https://caniuse.com/web-bluetooth).
## Features
@@ -16,29 +18,31 @@ A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE
### API Support Matrix
| API | Android | iOS | macOS | Windows (beta) | Linux (beta) | Web |
| :------------------- | :-----: | :-: | :---: | :-----: | :---: | :-: |
| startScan/stopScan | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| connect/disconnect | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| getConnectedDevices | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| discoverServices | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| readValue | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| writeValue | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| setNotifiable | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| pair/unPair | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ❌ |
| onPairingStateChange | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ❌ |
| enableBluetooth | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ❌ |
| onAvailabilityChange | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| requestMtu | ✔️ | ✔️ | ✔️ | ✔️ | 🚧 | ❌ |
| :------------------- | :-----: | :-: | :---: | :------------: | :----------: | :-: |
| startScan/stopScan | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| connect/disconnect | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| getConnectedDevices | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| discoverServices | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| readValue | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| writeValue | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| setNotifiable | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| pair/unPair | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ❌ |
| onPairingStateChange | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ❌ |
| enableBluetooth | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ❌ |
| onAvailabilityChange | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| requestMtu | ✔️ | ✔️ | ✔️ | ✔️ | 🚧 | ❌ |
## Getting Started
Add universal_ble in your pubspec.yaml:
```yaml
dependencies:
universal_ble:
```
and import it wherever you want to use it:
```dart
import 'package:universal_ble/universal_ble.dart';
```
@@ -188,4 +192,7 @@ UniversalBle.startScan(
// Create a class that extends UniversalBlePlatform
class UniversalBleMock extends UniversalBlePlatform {
// Implement all methods
}
}
UniversalBle.setInstance(UniversalBleMock());
```
+18 -3
View File
@@ -1,5 +1,6 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:universal_ble/universal_ble.dart';
import 'package:universal_ble_example/data/capabilities.dart';
@@ -35,6 +36,10 @@ class _MyAppState extends State<MyApp> {
void initState() {
super.initState();
/// Add common services for web
if (kIsWeb) {
_services.addAll(WebRequestOptionsBuilder.defaultServices);
}
_requestOptions =
WebRequestOptionsBuilder.acceptAllDevices(optionalServices: _services);
@@ -90,8 +95,17 @@ class _MyAppState extends State<MyApp> {
_scanResults.clear();
_isScanning = true;
});
await UniversalBle.startScan(
webRequestOptions: _requestOptions);
try {
await UniversalBle.startScan(
webRequestOptions: _requestOptions);
} catch (e) {
setState(() {
_isScanning = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(e.toString())),
);
}
},
),
PlatformButton(
@@ -103,7 +117,8 @@ class _MyAppState extends State<MyApp> {
});
},
),
if (Capabilities.supportsBluetoothEnableApi)
if (Capabilities.supportsBluetoothEnableApi &&
bleAvailabilityState == AvailabilityState.poweredOff)
PlatformButton(
text: 'Enable Bluetooth',
onPressed: () async {
@@ -90,24 +90,6 @@ class _PeripheralDetailPageState extends State<PeripheralDetailPage> {
}
}
Uint8List? _getWriteValue() {
if (!valueFormKey.currentState!.validate()) return null;
if (binaryCode.text.isEmpty) {
print("Error: No value to write");
return null;
}
List<int> hexList = [];
try {
hexList = hex.decode(binaryCode.text);
} catch (e) {
print("Error parsing hex $e");
}
return Uint8List.fromList(hexList);
}
Future<void> _discoverServices() async {
var services = await UniversalBle.discoverServices(widget.deviceId);
print('${services.length} services discovered');
@@ -115,6 +97,11 @@ class _PeripheralDetailPageState extends State<PeripheralDetailPage> {
setState(() {
discoveredServices = services;
});
if (kIsWeb) {
_addLog("DiscoverServices",
'${services.length} services discovered,\nNote: Only services added in WebRequestOptionsBuilder will be discoverd');
}
}
Future<void> _readValue() async {
@@ -134,9 +121,20 @@ class _PeripheralDetailPageState extends State<PeripheralDetailPage> {
}
Future<void> _writeValue() async {
Uint8List? value = _getWriteValue();
if (value == null || selectedCharacteristic == null) return;
print("Writing $value");
if (selectedCharacteristic == null ||
!valueFormKey.currentState!.validate() ||
binaryCode.text.isEmpty) {
return;
}
Uint8List value;
try {
value = Uint8List.fromList(hex.decode(binaryCode.text));
} catch (e) {
_addLog('WriteError', "Error parsing hex $e");
return;
}
try {
await UniversalBle.writeValue(
widget.deviceId,
@@ -314,7 +312,12 @@ class _PeripheralDetailPageState extends State<PeripheralDetailPage> {
if (value == null || value.isEmpty) {
return 'Please enter a value';
}
return null;
try {
hex.decode(binaryCode.text);
return null;
} catch (e) {
return 'Please enter a valid hex value ( without spaces or 0x (e.g. F0BB) )';
}
},
decoration: const InputDecoration(
hintText:
@@ -337,15 +340,16 @@ class _PeripheralDetailPageState extends State<PeripheralDetailPage> {
enabled: isConnected,
text: 'Discover Services',
),
PlatformButton(
enabled: isConnected,
onPressed: () async {
int mtu = await UniversalBle.requestMtu(
widget.deviceId, 247);
_addLog('MTU', mtu);
},
text: 'Request Mtu',
),
if (Capabilities.supportsRequestMtuApi)
PlatformButton(
enabled: isConnected,
onPressed: () async {
int mtu = await UniversalBle.requestMtu(
widget.deviceId, 247);
_addLog('MTU', mtu);
},
text: 'Request Mtu',
),
PlatformButton(
enabled: isConnected &&
discoveredServices.isNotEmpty &&
@@ -47,6 +47,20 @@ class WebRequestOptionsBuilder {
);
}
}
/// List of common services
static List<String> get defaultServices {
return BluetoothDefaultServiceUUIDS.values
.map((e) => e.uuid.toString())
.toList();
}
/// List of common services in 16 bit
static List<String> get defaultServices16Bit {
return BluetoothDefaultServiceUUIDS.values
.map((e) => e.uuid16.toString())
.toList();
}
}
/// To filter by name, namePrefix, services, manufacturerData
+6 -2
View File
@@ -1,9 +1,10 @@
name: universal_ble
description: A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter
version: 0.8.3
version: 0.8.4
homepage: https://navideck.com
repository: https://github.com/Navideck/universal_ble
issue_tracker: https://github.com/Navideck/universal_ble/issues
platforms:
android:
ios:
@@ -11,7 +12,7 @@ platforms:
macos:
web:
windows:
environment:
sdk: ">=3.1.3 <4.0.0"
flutter: ">=3.3.0"
@@ -30,6 +31,7 @@ dev_dependencies:
sdk: flutter
flutter_lints: ^2.0.0
pigeon: ^13.0.0
flutter:
plugin:
platforms:
@@ -44,3 +46,5 @@ flutter:
sharedDarwinSource: true
windows:
pluginClass: UniversalBlePluginCApi