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

BT Dialogs + Intl + Thoughts

parent 1c73af8e
{"_info":"// This is a generated file; do not edit or check into version control.","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":[]}]}
\ 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-20 08:02:35.622880","version":"1.14.6"}
\ No newline at end of file
# Stage Bulletpoints
## LogAir description
Keep same.
## Objectives
### Build an app
App capable of bridging LogAir's devices with LogAir's servers.
Should display processed information to the user.
Should be able to display relevant information of a map.
Should be accessible.
### API
Should enable getting data to display on maps or for tertiary use.
## Technical aspects
### App
Use the Dart programming language and the Flutter SDK to exploit the cross-OS deployment option, and the ease of development.
Use Bluetooth adapter functionality to capture streaming device data (`flutter_blue`).
Process the data locally (integrity verification, conversion to web compatible format)
Transmit data to the server using a socket on the server.
Display maps and layers, use a leaflet integration (`flutter_map`).
### nodejs API
Use `node.js` for the base API functionality.
Use `express` for routing.
## Steps
Develop a base layout to be used.
Develop Bluetooth handling systems (wrapped around `flutter_blue`)
Develop data display.
Develop transmission to server.
Develop API.
Develop map display.
Develop info display.
Develop options.
Develop internationalization.
Develop Social.
# Collection of thoughts and general development process
## [0.0.3] - future
Most of the UI updates can be based upon stream builder, will limit redraws and conserve.
IE. Battery value recuperated every 5 seconds via platform channel and if different than the one contained in the sink, add it to the sink.
Same concept for PM data.
### [0.0.3] Resources
## [0.0.2] - current
The idea for BLE is to use Platform specific code, ie `Platform channels`...
| Platform Specific | Cross OS |
| ------------------------ | ------------------------:|
| Stay Alive | Scan environment |
| | Scan named MAC addresses |
| | Write to File |
| Get Battery level ✅ | |
| Platform Specific | Cross OS |
| ---------------------------- | ----------------------------:|
| Stay Alive ✅ And | Scan environment ✅ |
| | Scan named MAC addresses ✅ |
| | Connect to device |
| Get Battery level ✅ | Read data stream |
Testing procedure for background will include the backup system as well (ie. writing to files).
......@@ -39,6 +49,16 @@ This is a tricky one.
Sadly, because Apple doesn't care about it's users, we will only be able to support devices running `iOS >= 7.X` (100% of iPad 1, 1.5% of iPad 2, 100% of iPhone 3GS, 8.3% of iPhone 4 and 100% of iPod Touch 4 ~= 0.1% of the ecosystem, allegedly, although the iPhone 4 is barely 7 years old).
Secondly, we have the issue of ios's bricky situation. As they have very strenouos limits as to what can and can't be used in background, and the notion of a background service is foreign to them, we can't have our app run as a background service like for Android. The rest of the app would work, just not the core part that transmits from point A to point B.
Another solution would be to add a counter to the firmware, store everything in a file, and then do a `sync` but that would imply more control on the hardware side.
Despite the development environment being a pain to work with, we can't even just distribute the app as a 3rd party, as Apple doesn't allow that (although Europe is throwing them judicial flak for it).
TestFlight is not a "viable" option, only allows 10000 beta testers and required the guarantee of it being beta (no production stuff).
Will require discussion obviously.
### [0.0.2] Resources
- [Permissions aaS](https://www.filledstacks.com/snippet/request-permissions-in-flutter-as-a-service/)
......@@ -57,6 +77,10 @@ Sadly, because Apple doesn't care about it's users, we will only be able to supp
- [Use to check wakedness](https://github.com/transistorsoft/flutter_background_fetch)
- [Workmanager](https://medium.com/vrt-digital-studio/flutter-workmanager-81e0cfbd6f6e) \[[Pub Repo](https://pub.dev/packages/workmanager)\]
- [flutter_map Pub repo](https://pub.dev/packages/flutter_map)
- [Apple Background Location Thread](https://forums.developer.apple.com/thread/69152)
- [Apple's take on the matter (it's useless)](https://developer.apple.com/documentation/corelocation/getting_the_user_s_location/handling_location_events_in_the_background)
- [And more details](https://stackoverflow.com/questions/43355538/best-practice-methods-to-keep-an-ios-ble-app-alive-in-the-background)
- [BTLE UUID's](https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/ble-services-a-beginners-tutorial)
## [0.0.1] - 05/02/2020
......
import 'package:uuid/uuid.dart';
class BtleUUID {
// TODO Function for service, characteristics parsing.
static final List<int> bluetoothLeCccd = Uuid().parse("00002902-0000-1000-8000-00805f9b34fb");
static final List<int> bluetoothLeCc254xService = Uuid().parse("0000ffe0-0000-1000-8000-00805f9b34fb");
static final List<int> bluetoothLeCc254xCharRw = Uuid().parse("0000ffe1-0000-1000-8000-00805f9b34fb");
static final List<int> bluetoothLeNrfService = Uuid().parse("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
static final List<int> bluetoothLeNrfCharRw2 = Uuid().parse("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
static final List<int> bluetoothLeNrfCharRw3 = Uuid().parse("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
static final List<int> bluetoothLeRn4870Service = Uuid().parse("49535343-fe7D-4ae5-8fa9-9fafd205e455");
static final List<int> bluetoothLeRn4870CharRw = Uuid().parse("49535343-1e4d-4bd9-ba61-23c647249616");
}
\ No newline at end of file
/// Constants enum defining the names of the platform channels used to communicate with platform specific code.
class Channels {
static const String BATTERY = 'logair.application/battery';
static const String BATTERY_CHARGE = 'logair.application/bsattery_charge_status';
......
......@@ -22,6 +22,11 @@ class BTLEHandler {
startScan() =>
_flutterBlueInstance.startScan(timeout: Duration(seconds: 5));
stopScan() =>
_flutterBlueInstance.stopScan();
Future<bool> isScanning() => _flutterBlueInstance.isScanning.first;
Future<List<BluetoothDevice>> get connectedDevices => _flutterBlueInstance.connectedDevices;
bool isDeviceConnected() => _device != null;
......@@ -35,6 +40,9 @@ class BTLEHandler {
return it.disconnect();
});
// TODO turn BTLE on method
turnBTLEOn() {}
String get address => this._device?.let((it) => it.id.toString());
BluetoothDevice _device;
......
{
"@@last_modified": "2020-02-05T17:25:56.614777",
"@@last_modified": "2020-02-20T07:40:18.875039",
"ok": "OK",
"@ok": {
"type": "text",
......@@ -10,6 +10,11 @@
"type": "text",
"placeholders": {}
},
"none": "None",
"@none": {
"type": "text",
"placeholders": {}
},
"locationPromptTitle": "This app needs to use location services",
"@locationPromptTitle": {
"description": "Title for the location permission request prompt",
......@@ -22,8 +27,8 @@
"type": "text",
"placeholders": {}
},
"bluetoothScanMessage": "Scan for Bluetooth Devices",
"@bluetoothScanMessage": {
"bluetoothAvailable": "Available Devices",
"@bluetoothAvailable": {
"type": "text",
"placeholders": {}
},
......@@ -32,8 +37,13 @@
"type": "text",
"placeholders": {}
},
"bluetoothAvailable": "Available Devices",
"@bluetoothAvailable": {
"bluetoothInactive": "Bluetooth is not active on this device.\nTurn it on ?",
"@bluetoothInactive": {
"type": "text",
"placeholders": {}
},
"bluetoothScanMessage": "Scan for Bluetooth Devices",
"@bluetoothScanMessage": {
"type": "text",
"placeholders": {}
},
......
......@@ -10,8 +10,13 @@
"type": "text",
"placeholders": {}
},
"locationTitle": "L'application requiert des permissions de localisation",
"@locationTitle": {
"none": "Aucun",
"@none": {
"type": "text",
"placeholders": {}
},
"locationPromptTitle": "L'application requiert des permissions de localisation",
"@locationPromptTitle": {
"description": "Titre pour l'annonce the requête de permissions de localisations",
"type": "text",
"placeholders": {}
......@@ -22,8 +27,8 @@
"type": "text",
"placeholders": {}
},
"bluetoothScanMessage": "Recherche d'appareils Bluetooth",
"@bluetoothScanMessage": {
"bluetoothAvailable": "Appareils Disponibles",
"@bluetoothAvailable": {
"type": "text",
"placeholders": {}
},
......@@ -32,8 +37,13 @@
"type": "text",
"placeholders": {}
},
"bluetoothAvailable": "Appareils Disponibles",
"@bluetoothAvailable": {
"bluetoothInactive": "Bluetooth n'est pas actif sur votre appareil.\nL'activer ?",
"@bluetoothInactive": {
"type": "text",
"placeholders": {}
},
"bluetoothScanMessage": "Recherche d'appareils Bluetooth",
"@bluetoothScanMessage": {
"type": "text",
"placeholders": {}
},
......
{
"@@last_modified": "2020-02-14T18:33:12.826799",
"@@last_modified": "2020-02-20T07:40:18.875039",
"ok": "OK",
"@ok": {
"type": "text",
......@@ -10,6 +10,11 @@
"type": "text",
"placeholders": {}
},
"none": "None",
"@none": {
"type": "text",
"placeholders": {}
},
"locationPromptTitle": "This app needs to use location services",
"@locationPromptTitle": {
"description": "Title for the location permission request prompt",
......@@ -22,8 +27,8 @@
"type": "text",
"placeholders": {}
},
"bluetoothScanMessage": "Scan for Bluetooth Devices",
"@bluetoothScanMessage": {
"bluetoothAvailable": "Available Devices",
"@bluetoothAvailable": {
"type": "text",
"placeholders": {}
},
......@@ -32,8 +37,13 @@
"type": "text",
"placeholders": {}
},
"bluetoothAvailable": "Available Devices",
"@bluetoothAvailable": {
"bluetoothInactive": "Bluetooth is not active on this device.\nTurn it on ?",
"@bluetoothInactive": {
"type": "text",
"placeholders": {}
},
"bluetoothScanMessage": "Scan for Bluetooth Devices",
"@bluetoothScanMessage": {
"type": "text",
"placeholders": {}
},
......
......@@ -23,11 +23,13 @@ class MessageLookup extends MessageLookupByLibrary {
static _notInlinedMessages(_) => <String, Function> {
"bluetoothAvailable" : MessageLookupByLibrary.simpleMessage("Available Devices"),
"bluetoothFrequent" : MessageLookupByLibrary.simpleMessage("Frequently Used Devices"),
"bluetoothInactive" : MessageLookupByLibrary.simpleMessage("Bluetooth is not active on this device.\nTurn it on ?"),
"bluetoothScanMessage" : MessageLookupByLibrary.simpleMessage("Scan for Bluetooth Devices"),
"bluetoothUnsupported" : MessageLookupByLibrary.simpleMessage("This device does not support Bluetooth Low Energy"),
"cancel" : MessageLookupByLibrary.simpleMessage("Cancel"),
"locationPromptReason" : MessageLookupByLibrary.simpleMessage("To use Bluetooth Low Energy and to increase data collection accuracy, this permission is required."),
"locationPromptTitle" : MessageLookupByLibrary.simpleMessage("This app needs to use location services"),
"none" : MessageLookupByLibrary.simpleMessage("None"),
"ok" : MessageLookupByLibrary.simpleMessage("OK")
};
}
......@@ -23,10 +23,13 @@ class MessageLookup extends MessageLookupByLibrary {
static _notInlinedMessages(_) => <String, Function> {
"bluetoothAvailable" : MessageLookupByLibrary.simpleMessage("Appareils Disponibles"),
"bluetoothFrequent" : MessageLookupByLibrary.simpleMessage("Appareils Fréquemment Utilisés"),
"bluetoothInactive" : MessageLookupByLibrary.simpleMessage("Bluetooth n\'est pas actif sur votre appareil.\nL\'activer ?"),
"bluetoothScanMessage" : MessageLookupByLibrary.simpleMessage("Recherche d\'appareils Bluetooth"),
"bluetoothUnsupported" : MessageLookupByLibrary.simpleMessage("Cette appareil n\'est pas compatible avec Bluetooth Low Energy"),
"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."),
"locationPromptTitle" : MessageLookupByLibrary.simpleMessage("L\'application requiert des permissions de localisation"),
"none" : MessageLookupByLibrary.simpleMessage("Aucun"),
"ok" : MessageLookupByLibrary.simpleMessage("OK")
};
}
......@@ -6,19 +6,19 @@ import 'package:logair_application/l10n/messages_all.dart' show initializeMessag
/// Reference https://github.com/dart-lang/intl https://pub.dev/packages/intl
/// Adding a localization should follow the guidelines defined here : https://github.com/flutter/website/blob/master/examples/internationalization/add_language/lib/main.dart
/// The frequent locales have already been integrated (but who knows when you'll need Belarusian).
class InternalLocalization {
class AppLocalization {
final String locale;
const InternalLocalization(this.locale);
const AppLocalization(this.locale);
static Future<InternalLocalization> load(Locale locale) {
static Future<AppLocalization> load(Locale locale) {
final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) => InternalLocalization(localeName));
return initializeMessages(localeName).then((_) => AppLocalization(localeName));
}
static InternalLocalization of(BuildContext context) => Localizations.of(context, InternalLocalization);
static AppLocalization of(BuildContext context) => Localizations.of(context, AppLocalization);
/* General Values */
......@@ -33,6 +33,11 @@ class InternalLocalization {
name: 'cancel',
);
String get none => Intl.message(
'None',
name: 'none'
);
/* Location Prompt */
String get locationPromptTitle => Intl.message(
'This app needs to use location services',
......@@ -47,9 +52,9 @@ class InternalLocalization {
);
/// Bluetooth Strings
String get bluetoothScanMessage => Intl.message(
'Scan for Bluetooth Devices',
name: 'bluetoothScanMessage',
String get bluetoothAvailable => Intl.message(
'Available Devices',
name: 'bluetoothAvailable'
);
String get bluetoothFrequent => Intl.message(
......@@ -57,9 +62,14 @@ class InternalLocalization {
name: 'bluetoothFrequent'
);
String get bluetoothAvailable => Intl.message(
'Available Devices',
name: 'bluetoothAvailable'
String get bluetoothInactive => Intl.message(
'Bluetooth is not active on this device.\nTurn it on ?',
name: 'bluetoothInactive'
);
String get bluetoothScanMessage => Intl.message(
'Scan for Bluetooth Devices',
name: 'bluetoothScanMessage',
);
String get bluetoothUnsupported => Intl.message(
......
import 'package:flutter/cupertino.dart';
import 'package:logair_application/localization/localization.dart';
class InternalLocalizationDelegate extends LocalizationsDelegate<InternalLocalization> {
const InternalLocalizationDelegate();
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalization> {
const AppLocalizationDelegate();
@override
bool isSupported(Locale locale) => ['en', 'fr'].contains(locale.languageCode);
@override
Future<InternalLocalization> load(Locale locale) => InternalLocalization.load(locale);
Future<AppLocalization> load(Locale locale) => AppLocalization.load(locale);
@override
bool shouldReload(InternalLocalizationDelegate old) => false;
bool shouldReload(AppLocalizationDelegate old) => false;
}
\ No newline at end of file
......@@ -21,15 +21,9 @@ class _StatsViewState extends State<StatsView> {
Widget build(BuildContext context) {
return BaseWidget(
builder: (context, sizingInfo) => GestureDetector(
onTap: () {
print('SIZING INFO : ${sizingInfo.toString()}');
print('SIZING INFO : ${sizingInfo.unnotchedHeight()}');
},
onVerticalDragStart: (details) {
gestureStartY = details.globalPosition.dy;
canChange = (sizingInfo.screenSize.height * 0.9 <= gestureStartY);
print('SIZING INFO : ${sizingInfo.toString()}');
},
onVerticalDragUpdate: (details) {
if (deltaSum >= 50 && canChange)
......@@ -43,7 +37,7 @@ class _StatsViewState extends State<StatsView> {
canChange = false;
deltaSum = 0.0;
if (change)
Navigator.pop(context);
Navigator.of(context).pop();
},
child: SafeArea(
child: Scaffold(
......
......@@ -22,8 +22,6 @@ class _BluetoothButtonState extends State<BluetoothButton> {
@override
Widget build(BuildContext context) {
// TODO shape circle
// TODO Circle with border.
return Material(
child: Ink(
decoration: BoxDecoration(
......@@ -37,6 +35,7 @@ class _BluetoothButtonState extends State<BluetoothButton> {
child: InkWell(
borderRadius: BorderRadius.circular(1000.0),
onTap: () {
print("onTap");
if (!this._bluetoothConnected)
this.onTapOn().then((value) {
print('Tap on $value');
......
......@@ -11,7 +11,6 @@ class BTLEScanTile extends StatelessWidget {
/// [VoidCallback] of actions to execute when the [Widget]'s [onTap] is triggered.
final VoidCallback onTap;
const BTLEScanTile({Key key, @required this.result, @required this.onTap}) : super(key: key);
@override
......
......@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
class SlimListTile extends StatelessWidget {
final String title;
final String subtitle;
SlimListTile({@required this.title, @required this.subtitle});
......
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.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_inactive_dialog.dart';
import 'package:logair_application/ui/dialog/bluetooth_selection_dialog.dart';
import 'package:logair_application/ui/dialog/bluetooth_unavailable_dialog.dart';
class DataWidget extends StatelessWidget {
DataWidget();
......@@ -26,7 +30,7 @@ class DataWidget extends StatelessWidget {
Text("Data", style: TextStyle(fontFamily: "Consolas", fontSize: 22)),
RaisedButton(
onPressed: () => {
// await BTLEHandler().dialog(ocntext)
// await BTLEHandler().dialog(context)
BTLEHandler().switchState()
},
child: Text('Toggle BTLE Service'),
......@@ -39,32 +43,8 @@ class DataWidget extends StatelessWidget {
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;
},
onTapOn: () => _onTapOn(context),
onTapOff: () => _onTapOff(context),
),
]
),
......@@ -73,6 +53,44 @@ class DataWidget extends StatelessWidget {
}
}
void _asyncTask() async {
_onTapOn(BuildContext context) async {
print('Check BTAvail');
bool _returnValue = await BTLEHandler().isBluetoothAvailable().then(
(bluetoothAvailable) async {
if (!bluetoothAvailable) {
showBluetoothUnavailableDialog(context);
print('BTLE availability check failed');
return false;
}
print('Check BTOn');
bool _returnValue = await BTLEHandler().isBluetoothActive().then((bluetoothOn) async {
bool _userConfirmed = false;
bool _returnValue = false;
if (!bluetoothOn) {
print('BTLE activity check failed');
_userConfirmed = await showBluetoothInactiveDialog(context).then((userConfirmed) async {
return userConfirmed;
});
} else
_userConfirmed = true;
}
\ No newline at end of file
// TODO Turn on BT or ask turn on BT. Method Channel ?
if (_userConfirmed) {
bool _returnValue = await showBluetoothSelectionDialog(context).then((value) => value);
return _returnValue;
} else
return false;
});
return _returnValue;
});
return _returnValue;
}
_onTapOff(BuildContext context) async {
BTLEHandler().disconnect();
return true;
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logair_application/localization/localization.dart';
Future<bool> showBluetoothInactiveDialog(BuildContext context) async {
bool _returnValue = await showDialog(
context: context,
barrierDismissible: false,
builder: (context) => SimpleDialog(
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Text(
AppLocalization.of(context).bluetoothInactive
),
SimpleDialogOption(
child: Text(
AppLocalization.of(context).cancel
),
onPressed: () => Navigator.of(context).pop(false),
),
SimpleDialogOption(
child: Text(
AppLocalization.of(context).ok
),
onPressed: () => Navigator.of(context).pop(true),
)
],
),
),
],
),
);
return _returnValue;
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:logair_application/localization/localization.dart';
import 'package:logair_application/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/localization/localization_delegate.dart';
import 'package:logair_application/ui/components/bt_scan_tile.dart';
import 'dart:convert';
......@@ -22,7 +23,7 @@ class Device {
String toString() => 'DEVICE $name@$address';
}
showBluetoothSelectionDialog(BuildContext context) async {
Future<bool> showBluetoothSelectionDialog(BuildContext context) async {
BTLEHandler().startScan();
/// Get the previous connections for this device.
......@@ -30,8 +31,9 @@ showBluetoothSelectionDialog(BuildContext context) async {
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(
bool _returnValue = await showDialog(
context: context,