Commit d8dcdda6 authored by Nicolas Richard Walter Boeckh's avatar Nicolas Richard Walter Boeckh 💬

BTLEHandler + Prefs + BT Button

+ BluetoothButton
+ INTL messages
+ BT Connection Handling
parent 3da72318
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.6.3+1\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.4.3\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.6.3+1\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.4.3\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"flutter_blue","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-02-12 15:05:29.450383","version":"1.14.7-pre.83"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.6.3+1\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.4.3\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.6.3+1\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.4.3\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"flutter_blue","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-02-14 14:34:10.918969","version":"1.14.7-pre.83"}
\ No newline at end of file
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart"
}
]
}
\ No newline at end of file
{
"java.configuration.updateBuildConfiguration": "interactive"
"java.configuration.updateBuildConfiguration": "interactive",
"files.exclude": {
"**/.classpath": true,
"**/.project": true,
"**/.settings": true,
"**/.factorypath": true
}
}
\ No newline at end of file
......@@ -28,26 +28,32 @@ Dates are in the sensible `DD/MM/YYYY` format.
## [0.0.2] - current
### Summary
### [0.0.2] Summary
### Added
### [0.0.2] Added
- Next : Disconnect from BTLE device before allowing reconnection.
- (UI) `BluetoothButton` : Will check BT availability, BT is on, BT is connected.
- (OS) `SharedPreferences` storage access and reference storage
- (OS) Connecting to BTLE devices
- (OS) Scanning for BTLE devices
- (UI) Dialog to connect with BTLE devices
- (OS) Platform dependent code to get battery percentage value - Used as an introduction to platform dependent code, ie. what will be used for BLE.
- (Lang) fr localization.
- (Lang) en/fr localization.
### Changed
### [0.0.2] Changed
- Changed minSdk to version 19 (from 18) to support `rx_ble` library integration.
- (Req) `minSdk` to 19 for `flutter_blue`
### Removed
### [0.0.2] Removed
## [0.0.1] - 05/02/2020
### Summary
### [0.0.1] Summary
Added a basic UI and support for Internationalization, out of the box.
### Added
### [0.0.1] Added
- (UI) Permission Dialog.
- (UX) Internationalization support.
......@@ -61,8 +67,8 @@ Added a basic UI and support for Internationalization, out of the box.
- (UI) Carousel widget.
- (UI) Base Widget as base building block -> Enables responsiveness in UI scaling.
### Changed
### [0.0.1] Changed
### Removed
### [0.0.1] Removed
## Released
......@@ -38,7 +38,6 @@ android {
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.logair.logair_application"
minSdkVersion 19
targetSdkVersion 28
......
import 'dart:async';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:kotlin_flavor/scope_functions.dart';
import 'package:logair_application/platform/wake_service.dart';
class BTLEHandler {
static final BTLEHandler _singleton = new BTLEHandler._internal();
static bool started = false;
static Duration duration = new Duration(seconds: 1);
Timer t;
FlutterBlue _flutterBlueInstance = FlutterBlue.instance;
factory BTLEHandler() => _singleton;
BTLEHandler._internal() {
_flutterBlueInstance.setLogLevel(LogLevel.info);
}
startScan() =>
_flutterBlueInstance.startScan(timeout: Duration(seconds: 5));
Future<List<BluetoothDevice>> get connectedDevices => _flutterBlueInstance.connectedDevices;
Stream<List<ScanResult>> get scanResults => _flutterBlueInstance.scanResults;
Future<void> connect() => this._device?.let((it) => it.connect());
Future<dynamic> disconnect() => this._device?.let((it) {
_device = null;
return it.disconnect();
});
String get address => this._device?.let((it) => it.id.toString());
BluetoothDevice _device;
setDevice(BluetoothDevice device) => device?.let((it) => this._device = it);
bool switchState() {
if (started)
_end();
else
_start();
return started;
}
void _start() {
WakeService().modifyWakeService(true).then((value) => print('Device will stay awake $value'));
started = true;
t = new Timer.periodic(duration, (Timer t) => print("${new DateTime.now()}"));
}
void _end() {
WakeService().modifyWakeService(false).then((value) => print('Device will stay awake $value'));
t.cancel();
}
import 'dart:async';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:kotlin_flavor/scope_functions.dart';
import 'package:logair_application/platform/wake_service.dart';
/// Serves as a wrapper class around [FlutterBlue], and helps integrate it into the application with extensions
class BTLEHandler {
static final BTLEHandler _singleton = new BTLEHandler._internal();
static bool started = false;
static Duration duration = new Duration(seconds: 1);
Timer t;
FlutterBlue _flutterBlueInstance = FlutterBlue.instance;
factory BTLEHandler() => _singleton;
BTLEHandler._internal() {
_flutterBlueInstance.setLogLevel(LogLevel.info);
}
startScan() =>
_flutterBlueInstance.startScan(timeout: Duration(seconds: 5));
Future<List<BluetoothDevice>> get connectedDevices => _flutterBlueInstance.connectedDevices;
bool isDeviceConnected() => _device != null;
Stream<List<ScanResult>> get scanResults => _flutterBlueInstance.scanResults;
Future<void> connect() => this._device?.let((it) => it.connect());
Future<dynamic> disconnect() => this._device?.let((it) {
_device = null;
return it.disconnect();
});
String get address => this._device?.let((it) => it.id.toString());
BluetoothDevice _device;
Future<bool> isBluetoothAvailable() => _flutterBlueInstance.isAvailable;
Future<bool> isBluetoothActive() => _flutterBlueInstance.isOn;
setDevice(BluetoothDevice device) => device?.let((it) => this._device = it);
bool switchState() {
if (started)
_end();
else
_start();
return started;
}
void _start() {
WakeService().modifyWakeService(true).then((value) => print('Device will stay awake $value'));
started = true;
t = new Timer.periodic(duration, (Timer t) => print("${new DateTime.now()}"));
}
void _end() {
WakeService().modifyWakeService(false).then((value) => print('Device will stay awake $value'));
t.cancel();
}
}
\ No newline at end of file
import 'package:shared_preferences/shared_preferences.dart';
class PreferencesHandler {
static final PreferencesHandler _singleton = new PreferencesHandler._internal();
SharedPreferences _sharedPreferences;
PreferencesHandler._internal();
Future<SharedPreferences> getPreferences() async {
if (_sharedPreferences == null) {
_sharedPreferences = await SharedPreferences.getInstance();
}
return _sharedPreferences;
}
factory PreferencesHandler() => _singleton;
}
\ No newline at end of file
......@@ -26,5 +26,15 @@
"@bluetoothScanMessage": {
"type": "text",
"placeholders": {}
},
"bluetoothFrequent": "Frequently Used Devices",
"@bluetoothFrequent": {
"type": "text",
"placeholders": {}
},
"bluetoothAvailable": "Available Devices",
"@bluetoothAvailable": {
"type": "text",
"placeholders": {}
}
}
\ No newline at end of file
......@@ -26,5 +26,15 @@
"@bluetoothScanMessage": {
"type": "text",
"placeholders": {}
},
"bluetoothFrequent": "Appareils Fréquemment Utilisés",
"@bluetoothFrequent": {
"type": "text",
"placeholders": {}
},
"bluetoothAvailable": "Appareils Disponibles",
"@bluetoothAvailable": {
"type": "text",
"placeholders": {}
}
}
\ No newline at end of file
{
"@@last_modified": "2020-02-12T00:51:00.943793",
"@@last_modified": "2020-02-13T17:57:48.355903",
"ok": "OK",
"@ok": {
"type": "text",
......@@ -26,5 +26,15 @@
"@bluetoothScanMessage": {
"type": "text",
"placeholders": {}
},
"bluetoothFrequent": "Frequently Used Devices",
"@bluetoothFrequent": {
"type": "text",
"placeholders": {}
},
"bluetoothAvailable": "Available Devices",
"@bluetoothAvailable": {
"type": "text",
"placeholders": {}
}
}
\ No newline at end of file
......@@ -21,6 +21,8 @@ class MessageLookup extends MessageLookupByLibrary {
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
"bluetoothAvailable" : MessageLookupByLibrary.simpleMessage("Available Devices"),
"bluetoothFrequent" : MessageLookupByLibrary.simpleMessage("Frequently Used Devices"),
"bluetoothScanMessage" : MessageLookupByLibrary.simpleMessage("Scan for Bluetooth Devices"),
"cancel" : MessageLookupByLibrary.simpleMessage("Cancel"),
"locationPromptReason" : MessageLookupByLibrary.simpleMessage("To use Bluetooth Low Energy and to increase data collection accuracy, this permission is required."),
......
......@@ -21,6 +21,8 @@ class MessageLookup extends MessageLookupByLibrary {
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
"bluetoothAvailable" : MessageLookupByLibrary.simpleMessage("Appareils Disponibles"),
"bluetoothFrequent" : MessageLookupByLibrary.simpleMessage("Appareils Fréquemment Utilisés"),
"bluetoothScanMessage" : MessageLookupByLibrary.simpleMessage("Recherche d\'appareils Bluetooth"),
"cancel" : MessageLookupByLibrary.simpleMessage("Annuler"),
"locationPromptReason" : MessageLookupByLibrary.simpleMessage("Afin d\'augmenter la précision de la localisation et pour utiliser Bluetooth Low Energy, cette permission est nécessaire."),
......
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:logair_application/l10n/messages_all.dart' show initializeMessages;
......@@ -50,4 +51,14 @@ class InternalLocalization {
'Scan for Bluetooth Devices',
name: 'bluetoothScanMessage',
);
String get bluetoothFrequent => Intl.message(
'Frequently Used Devices',
name: 'bluetoothFrequent'
);
String get bluetoothAvailable => Intl.message(
'Available Devices',
name: 'bluetoothAvailable'
);
}
......@@ -3,7 +3,10 @@
*
*/
/// Represents 1 second of data streamed from LogAir's devices,
/// and contains methods for:
/// quick lookup,
/// conversion to POST format,
class DataPacket {
String _data;
int _timeStamp;
......
......@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:device_preview/device_preview.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:logair_application/localization/localization_delegate.dart';
import 'package:logair_application/platform/bluetooth_le_service.dart';
import 'package:logair_application/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/routes/home.dart';
// TODO Lang service, initialized with the right locale, where accessible from entire program
......@@ -16,7 +16,6 @@ void main() => runApp(displayMode ? DevicePreview(child: LogAirApplication()) :
class LogAirApplication extends StatelessWidget {
static const String _title = 'LogAir Connector';
// This widget is the root of your Wpplication.
@override
Widget build(BuildContext context) {
BTLEHandler();
......
......@@ -3,10 +3,10 @@ import 'package:logair_application/enums/platform_channels.dart';
class WakeService {
static const MethodChannel methodChannel = const MethodChannel(Channels.WAKE);
static final WakeService _singleton = new WakeService._internal();
factory WakeService() {
return _singleton;
}
factory WakeService() => _singleton;
WakeService._internal();
......
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';
class BluetoothButton extends StatefulWidget {
final Function onTapOn;
final Function onTapOff;
BluetoothButton({Key key, @required this.onTapOn, @required this.onTapOff}) : super(key: key);
@override
_BluetoothButtonState createState() => _BluetoothButtonState(onTapOn: this.onTapOn, onTapOff: this.onTapOff);
}
class _BluetoothButtonState extends State<BluetoothButton> {
bool _bluetoothConnected = false;
final Function onTapOn;
final Function onTapOff;
_BluetoothButtonState({Key key, @required this.onTapOn, @required this.onTapOff});
@override
Widget build(BuildContext context) {
// TODO shape circle
// TODO Circle with border.
return Material(
child: Ink(
decoration: BoxDecoration(
border: Border.all(
color: Colors.indigoAccent,
width: 2.0,
),
color: _bluetoothConnected ? Colors.blue[200] : Colors.white,
shape: BoxShape.circle,
),
child: InkWell(
borderRadius: BorderRadius.circular(1000.0),
onTap: () {
if (!this._bluetoothConnected)
this.onTapOn().then((value) {
print('Tap on $value');
if (value)
setState(() => {
_bluetoothConnected = !_bluetoothConnected
});
});
else
this.onTapOff().then((value) {
print('Tap off $value');
if (value)
setState(() => {
_bluetoothConnected = !_bluetoothConnected
});
});
},
child: Padding(
padding: EdgeInsets.all(10),
child: Icon(
Icons.bluetooth,
color: _bluetoothConnected ? Colors.grey : Colors.red,
size: 30.0,
),
),
)
),
);
}
}
\ No newline at end of file
......@@ -5,22 +5,22 @@ import 'package:flutter_blue/flutter_blue.dart';
import 'package:logair_application/ui/components/slim_list_tile.dart';
class BTLEScanTile extends StatelessWidget {
/// The [ScanResult] on which the information is based.
final ScanResult result;
/// [VoidCallback] of actions to execute when the [Widget]'s [onTap] is triggered.
final VoidCallback onTap;
const BTLEScanTile({Key key, this.result, this.onTap}) : super(key: key);
Widget _title(BuildContext context) {
return SlimListTile(
title: result.device.name,
subtitle: result.device.id.toString(),
);
}
const BTLEScanTile({Key key, @required this.result, @required this.onTap}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
title: _title(context),
title: SlimListTile(
title: result.device.name,
subtitle: result.device.id.toString(),
),
onTap: (result.advertisementData.connectable) ? onTap : null,
);
}
......
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:logair_application/platform/bluetooth_le_service.dart';
import 'package:logair_application/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/ui/carousel_card.dart';
import 'package:logair_application/platform/battery_service.dart';
import 'package:logair_application/ui/components/bluetooth_button.dart';
import 'package:logair_application/ui/dialog/bluetooth_selection_dialog.dart';
class DataWidget extends StatelessWidget {
......@@ -36,10 +37,42 @@ class DataWidget extends StatelessWidget {
showBluetoothSelectionDialog(context)
},
child: Text("BTLE popup")
)
),
BluetoothButton(
onTapOn: () async {
bool bluetoothAvailable = await BTLEHandler().isBluetoothAvailable();
if (!bluetoothAvailable) {
// DIALOG WITH ERROR
print('BTLE availability check failed');
return false;
}
bool bluetoothOn = await BTLEHandler().isBluetoothActive();
if (!bluetoothOn) {
// DIALOG WITH ALLOW TO TURN ON BTLE, conditional return.
print('BTLE availability check failed');
return false;
}
// TODO Check BT Availability
// TODO Check BT ON
// TODO Call dialog from here
// Can return from here.
showBluetoothSelectionDialog(context);
return true;
},
onTapOff: () async {
BTLEHandler().disconnect();
return true;
},
),
]
)
),
);
return CarouselCard(child: widget, color: Colors.green);
}
}
void _asyncTask() async {
}
\ No newline at end of file
......@@ -3,11 +3,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:logair_application/localization/localization.dart';
import 'package:logair_application/platform/bluetooth_le_service.dart';
import 'package:logair_application/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/ui/components/bt_scan_tile.dart';
import 'package:logair_application/ui/components/slim_list_tile.dart';
import 'dart:convert';
import 'package:logair_application/handlers/preference_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Device {
......@@ -22,16 +22,12 @@ class Device {
String toString() => 'DEVICE $name@$address';
}
// TODO on BT button press: Either isConnected so dialog disconnect, or isNotConnected so dialog connect use app state otherwise
showBluetoothSelectionDialog(BuildContext context) async {
// TODO Catch BT disabled
BTLEHandler().startScan();
/// Get the previous connections for this device.
SharedPreferences prefs = await SharedPreferences.getInstance();
List<Device> _frequentDevices = List.from(json.decode((prefs.getString('json') ?? '[ {"name": "logair7003", "address": "19:08:10:17:17:1C" } ]')).map((device) => Device(name: device["name"], address: device["address"]))); // await Devices, filter with cached values
SharedPreferences prefs = await PreferencesHandler().getPreferences();
List<Device> _frequentDevices = List.from(json.decode((prefs.getString('json') ?? '[ ]')).map((device) => Device(name: device["name"], address: device["address"]))); // await Devices, filter with cached values
print(_frequentDevices);
showDialog(
......@@ -53,27 +49,6 @@ showBluetoothSelectionDialog(BuildContext context) async {
),
),
Divider(),
Text("Connected devices"),
/// Currently connected BT Devices.
StreamBuilder<List<BluetoothDevice>>(
stream: Stream.periodic(Duration(seconds: 2)).asyncMap((_) => BTLEHandler().connectedDevices),
initialData: [],
builder: (context, snapshot) => Column(
children: snapshot.data.map(
(device) => ListTile(
title: SlimListTile(
title: device.name,
subtitle: device.id.toString(),
),
onTap: () {
if (BTLEHandler().address == device.id.toString())
BTLEHandler().disconnect();
}
),
).toList(),
),
),
Divider(),
Text("Frequent"),
StreamBuilder<List<ScanResult>>(
stream: BTLEHandler().scanResults.transform(
......@@ -86,10 +61,10 @@ showBluetoothSelectionDialog(BuildContext context) async {
builder: (context, snapshot) => Column(
children: (snapshot.data.length > 0) ?
snapshot.data.map(
(data) => BTLEScanTile(
result: data,
(result) => BTLEScanTile(
result: result,
onTap: () {
BTLEHandler().setDevice(data.device);
BTLEHandler().setDevice(result.device);
BTLEHandler().connect();
Navigator.of(context).pop();
}
......@@ -115,10 +90,10 @@ showBluetoothSelectionDialog(BuildContext context) async {
builder: (context, snapshot) => Column(
children: (snapshot.data.length > 0) ?
snapshot.data.map(
(data) => BTLEScanTile(
result: data,
(result) => BTLEScanTile(
result: result,
onTap: () {
BTLEHandler().setDevice(data.device);
BTLEHandler().setDevice(result.device);
BTLEHandler().connect();
Navigator.of(context).pop();
}
......@@ -139,7 +114,4 @@ showBluetoothSelectionDialog(BuildContext context) async {
);
}
);
}
_getFrequentDevices() async {
}
\ No newline at end of file
......@@ -17,11 +17,11 @@ class PermissionDialog extends StatelessWidget {
content: Text(dialogText),