Commit fa66a876 authored by Nicolas Richard Walter Boeckh's avatar Nicolas Richard Walter Boeckh 💬
Browse files

Preference Integration Most valuable done

Added :
- Network Mobile network && Preferences check
- General share check
- Bluetooth S_UUID and C_UUID to preferences
- Preferences for Location Accuracy (need integration and observable)
- Overview widgets and generic decoration
- Finished preferences menu
parent 9df25a57
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","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.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","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.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_macos-0.1.0+4\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-0.0.1+8\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"connectivity_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_for_web-0.3.1+2\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-0.1.2+5\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos","connectivity_for_web"]},{"name":"connectivity_for_web","dependencies":[]},{"name":"connectivity_macos","dependencies":[]},{"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":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-09-06 03:24:06.407665","version":"1.21.0-10.0.pre.193"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","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.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","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.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_macos-0.1.0+4\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-0.0.1+8\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"connectivity_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_for_web-0.3.1+2\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-0.1.2+5\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos","connectivity_for_web"]},{"name":"connectivity_for_web","dependencies":[]},{"name":"connectivity_macos","dependencies":[]},{"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":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-09-07 01:52:18.814120","version":"1.21.0-10.0.pre.193"}
\ No newline at end of file
......@@ -158,12 +158,9 @@ class MapDisplayController {
}
});
// TODO Set user defined duration
// TODO Set user defined radius
new Timer.periodic(Duration(minutes: 1), (Timer t) {
if (this._controller != null && this._controller.bounds != null) {
print('${this._controller.bounds.southWest}, ${this._controller.bounds.northEast}');
//print('${this._controller.bounds.southWest}, ${this._controller.bounds.northEast}');
NetworkHandler().getProximityPoints(DataHeader().deviceID, this._controller.bounds);
}
});
......
import 'package:collection/collection.dart';
import 'package:flutter/cupertino.dart';
/// @ToDeprecate Describes the contents of the data packets
/// @ReplaceBy Includes the device name and a config_file URL
......@@ -23,6 +24,11 @@ class DataHeader {
this._headerSet = true;
}
void setHeaderFromExisting({String deviceId = '', String url = ''}) {
this._headerData = [deviceID, url];
this._headerSet = true;
}
/// Retrieve the deviceID from the header
String get deviceID => (this._headerData != null && this._headerData.length > 0) ? this._headerData[0] : '';
String get url => (this._headerData != null && this._headerData.length > 0) ? this._headerData[1] : '';
......@@ -46,4 +52,18 @@ class DataHeader {
this._headerSet = false;
this._headerData = [];
}
Stream<String> deviceIdStream() async* {
while(true) {
yield this.deviceID;
await Future.delayed(Duration(seconds: 1));
}
}
Stream<int> deviceBatteryLevel() async* {
while(true) {
yield -1;
await Future.delayed(Duration(seconds: 1));
}
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import 'package:logair_application/utils/utils.dart';
class DataPacket {
List<int> _data;
int _timestamp;
String _deviceId;
/* Location variables */
double _latitude;
......@@ -33,6 +34,7 @@ class DataPacket {
String _extraData;
int timestamp() => _timestamp;
String deviceId() => _deviceId ?? '';
double latitude() => _latitude;
double longitude() => _longitude;
int altitude() => _altitude;
......@@ -80,6 +82,7 @@ class DataPacket {
// TODO Guard clause
DataPacket.fromMappedData(Map<String, dynamic> data) {
this._deviceId = data['device_id'];
this._timestamp = data['timestamp_nix'];
this._latitude = data['latitude'];
this._longitude = data['longitude'];
......
......@@ -4,17 +4,15 @@ import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:kotlin_flavor/scope_functions.dart';
import 'package:logair_application/logic/handlers/bluetooth_wake_handler.dart';
import 'package:logair_application/logic/handlers/preference_handler.dart';
import 'package:logair_application/services/wake_service.dart';
import 'package:logair_application/utils/enums/bluetooth_connection_status.dart';
import 'package:logair_application/logic/handlers/data_handler.dart';
import 'package:logair_application/utils/enums/preference_keys.dart';
/// Serves as a wrapper class around [FlutterBlue], and helps integrate it into the application with extensions
class BTLEHandler {
/// Static values used by the chip.
/// TODO Optionize (ongoing see [PreferencesHandler]) ?
static final String bluetoothLeCc254xServiceUUID = "0000ffe0-0000-1000-8000-00805f9b34fb";
static final String bluetoothLeCc254xReadUUID = "0000ffe1-0000-1000-8000-00805f9b34fb";
/// [Singleton]() instantiation factory.
factory BTLEHandler() => _singleton;
......@@ -82,6 +80,7 @@ class BTLEHandler {
_device = null;
_bluetoothConnectionStatus = BluetoothConnectionStatus.BTSTATUS_NOT_STREAMING;
DataHandler().dispose();
BTWakeHandler().switchState(start: false);
return it.disconnect();
});
......@@ -94,6 +93,11 @@ class BTLEHandler {
bool success = false;
if (this._device != null) {
final String bluetoothLeCc254xServiceUUID = await PreferencesHandler().getPreferencesString(PreferenceKeys.BT__SERVICE_UUID.key);
final String bluetoothLeCc254xReadUUID = await PreferencesHandler().getPreferencesString(PreferenceKeys.BT__CHARACTERISTIC_UUID.key);
print('$bluetoothLeCc254xServiceUUID\n$bluetoothLeCc254xReadUUID');
/// Get the first round of [BluetoothService]s and apply filter to desired Service UUID.
services = await this._device.services.first;
services = services.where((s) => s.uuid.toString() == bluetoothLeCc254xServiceUUID).toList();
......@@ -162,5 +166,6 @@ class BTLEHandler {
await this._device.discoverServices();
await _setupCharacteristics();
await _setupListener();
BTWakeHandler().switchState(start: true);
}
}
\ No newline at end of file
......@@ -11,18 +11,12 @@ class BTWakeHandler {
static final BTWakeHandler _singleton = BTWakeHandler._internal();
/// TODO Used for debugging, remove
Timer _t;
/// TODO Used for debugging, remove
static Duration _duration = new Duration(seconds: 1);
static bool _wakeServiceActive = false;
bool switchState() {
if (_wakeServiceActive)
bool switchState({bool start}) {
if (_wakeServiceActive || !start)
_end();
else
else if (!_wakeServiceActive || start)
_start();
return _wakeServiceActive;
......@@ -31,12 +25,10 @@ class BTWakeHandler {
void _start() {
WakeService().modifyWakeService(true).then((value) => print('_device will stay awake $value'));
_wakeServiceActive = 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'));
_wakeServiceActive = false;
_t.cancel();
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:collection';
import 'package:connectivity/connectivity.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:http/http.dart' as http;
......@@ -9,6 +10,9 @@ import 'package:logair_application/logic/data_header.dart';
import 'package:logair_application/logic/data_packet.dart';
import 'package:logair_application/logic/handlers/data_handler.dart';
import 'package:logair_application/logic/handlers/database_handler.dart';
import 'package:logair_application/logic/handlers/preference_handler.dart';
import 'package:logair_application/utils/enums/preference_keys.dart';
import 'package:rxdart/rxdart.dart';
import 'package:tuple/tuple.dart';
/// This singleton data structure that contains services enabling the application to send data to a webserver.
......@@ -16,30 +20,81 @@ class NetworkHandler {
factory NetworkHandler() => _singleton;
NetworkHandler._internal() {
// TODO Preferences
this._pushFrequency.listen((value) {
if (value != this._oldPushFrequency) {
if (this._timer != null) {
this._timer.cancel();
}
this._timer = null;
this._duration = Duration(seconds: value);
this._timer = new Timer.periodic(this._duration, (Timer t) => this._sendDataToServer());
this._oldPushFrequency = value;
}
});
/// Define the interval between attempts to send the data to the server. (default: 1 minute).
const duration = const Duration(minutes: 1);
new Timer.periodic(duration, (Timer t) => this._sendDataToServer());
PreferencesHandler().getPreferencesInt(PreferenceKeys.NET__MAX_ITEMS_PER_PUSH.key).then((value) => this._pushAmount.value = value);
PreferencesHandler().getPreferencesInt(PreferenceKeys.NET__TIME_TO_PUSH.key).then((value) => this._pushFrequency.value = value);
new Timer.periodic(Duration(seconds: 20), (Timer t) async {
this._pushAmount.value = await PreferencesHandler().getPreferencesInt(PreferenceKeys.NET__MAX_ITEMS_PER_PUSH.key);
this._pushFrequency.value = await PreferencesHandler().getPreferencesInt(PreferenceKeys.NET__TIME_TO_PUSH.key);
});
}
static final NetworkHandler _singleton = new NetworkHandler._internal();
@override
NetworkHandler.dispose() {
if (this._timer != null) {
this._timer.cancel();
this._timer = null;
}
_pushAmount.close();
_pushFrequency.close();
}
static final NetworkHandler _singleton = new NetworkHandler._internal();
DateTime _lastServerTransmission;
int a = 0;
BehaviorSubject<int> _pushAmount = BehaviorSubject<int>();
BehaviorSubject<int> _pushFrequency = BehaviorSubject<int>();
int _oldPushFrequency = -1;
Duration _duration;
Timer _timer;
Future<bool> checkNetworkAllowed() async {
ConnectivityResult connectivity = await Connectivity().checkConnectivity();
return !(connectivity == ConnectivityResult.none ||
(connectivity == ConnectivityResult.mobile && !(await PreferencesHandler().getPreferencesBool(PreferenceKeys.NET__USE_MOBILE_NET.key))));
}
/// Method to send acquired data packets by using a POST requests.
void _sendDataToServer() async {
// Check whether on mobile networks, and whether the user has allowed connectivity on mobile networks.
if (!(await checkNetworkAllowed() &&
await PreferencesHandler().getPreferencesBool(PreferenceKeys.GEN__SHARE.key))) {
return;
}
/// The default endpoint.
String url = 'https://api.logair.unige.ch/v1/service';
if (await DatabaseHandler().getUnsentPacketsLength().first > 0) {
DataPacket source = (await DatabaseHandler().getUnsent(_pushAmount.value ?? PreferenceKeys.NET__MAX_ITEMS_PER_PUSH.defaultValue))[0].item2;
// TODO set url / clean up
DataHeader().setHeaderFromExisting(deviceId: source.deviceId(), url: '');
}
/// Break conditions ([DataHeader] unset or no [DataPacket] available).
if (!DataHeader().headerSet || DataHandler().getData().length == 0)
else if (!DataHeader().headerSet || DataHandler().getData().length == 0)
return;
/// Get the map representation of a [DataHeader].
Map<String, dynamic> headerData = DataHeader().jsonify();
List<Tuple2<int, DataPacket>> databaseData = await DatabaseHandler().getUnsent(100);
List<Tuple2<int, DataPacket>> databaseData = await DatabaseHandler().getUnsent(_pushAmount.value ?? PreferenceKeys.NET__MAX_ITEMS_PER_PUSH.defaultValue);
/// Get all the [DataPacket]s to be sent (maximum 100).
List<DataPacket> packets = databaseData.map((x) => x.item2).toList();
......@@ -79,8 +134,12 @@ class NetworkHandler {
}
}
// TODO Set user defined duration
// TODO Set user defined radius
/// Get all of the points in proximity to the device.
void getProximityPoints(String deviceId, LatLngBounds bounds) async {
if (!(await checkNetworkAllowed())) return;
/// The default endpoint.
String url = 'https://api.logair.unige.ch/v1/geo/bounds?device_id=$deviceId&lat1=${bounds.northEast.latitude}&lng1=${bounds.northEast.longitude}&lat2=${bounds.southWest.latitude}&lng2=${bounds.southWest.longitude}&age=${300000}&limit=${200}';
/// Attempt to send the data to the endpoint via HTTP POST request.
......
......@@ -29,14 +29,14 @@ class PositionHandler {
int _timeSinceLastChange = 0;
/// Default location tweaking options.
/// TODO User configurable ?
/// TODO GPS.ACCURACY integrate
LocationOptions locationOptions = LocationOptions(accuracy: LocationAccuracy.high, distanceFilter: 0, timeInterval: 1);
/// Get whether the user has granted the location permissions.
Stream<GeolocationStatus> getGeolocationStatus() async* {
while (true) {
yield _geolocationStatus;
await Future.delayed(Duration(seconds: 2));
await Future.delayed(Duration(seconds: 1));
}
}
......
......@@ -7,7 +7,9 @@ class PreferencesHandler {
factory PreferencesHandler() => _singleton;
PreferencesHandler._internal();
PreferencesHandler._internal() {
this._sharedPreferences;
}
/// The singleton reference to the [SharedPreferences] instance.
SharedPreferences _sharedPreferencesInternal;
......@@ -18,7 +20,7 @@ class PreferencesHandler {
/// This enables the retrieval of the [SharedPreferences] ecosystem and setting it up if needed first.
Future<SharedPreferences> get _sharedPreferences async {
if (_sharedPreferencesInternal == null && !this._setup) {
print('Sean Connery says: Shetup.');
/// If some of the [PreferenceKeys] have mismatched types set to their default values.
if (!PreferenceKeys.assertTypesMatch())
throw new Exception('A <defaultValue<T>, T> pair is mismatched');
......@@ -46,7 +48,7 @@ class PreferencesHandler {
setter(prefs.defaultKey, prefs.defaultValue);
}
});
print('Setup preferences done\n ${List.generate(this._sharedPreferencesInternal.getKeys().length, (i) => this._sharedPreferencesInternal.getKeys().elementAt(i) + ' => ' + this._sharedPreferencesInternal.get(this._sharedPreferencesInternal.getKeys().elementAt(i)).toString()).join("\n")}');
//print('Setup preferences done\n ${List.generate(this._sharedPreferencesInternal.getKeys().length, (i) => this._sharedPreferencesInternal.getKeys().elementAt(i) + ' => ' + this._sharedPreferencesInternal.get(this._sharedPreferencesInternal.getKeys().elementAt(i)).toString()).join("\n")}');
this._setup = true;
}
......@@ -65,18 +67,26 @@ class PreferencesHandler {
/// Retrieves a [dynamic] from the [SharedPreferences].
Future<dynamic> getPreferences(String key) async => (await this._sharedPreferences).get(key);
/// Sets an [int] within the [SharedPreferences].
Future<void> setPreferencesInt(String key, int value) async => (await this._sharedPreferences).setInt(key, value);
Future<void> setPreferencesInt(String key, int value) async {
//print('Setting $key to $value');
(await this._sharedPreferences).setInt(key, value);
}
/// Sets a [String] within the [SharedPreferences].
Future<void> setPreferencesString(String key, String value) async => (await this._sharedPreferences).setString(key, value);
Future<void> setPreferencesString(String key, String value) async {
//print('Setting $key to $value');
(await this._sharedPreferences).setString(key, value);
}
/// Sets a [bool] within the [SharedPreferences].
Future<void> setPreferencesBool(String key, bool value) async => (await this._sharedPreferences).setBool(key, value);
Future<void> setPreferencesBool(String key, bool value) async {
// print('Setting $key to $value');
(await this._sharedPreferences).setBool(key, value);
}
/// Resets a specific [SharedPreferences] value to it's default value.
Future<void> resetPreferences(String key) async {
Future<void> resetPreference(String key) async {
Function setter;
PreferenceKeys pref = PreferenceKeys.get(key);
switch (pref.type) {
......@@ -88,17 +98,23 @@ class PreferencesHandler {
break;
case String:
setter = setPreferencesString;
break;
}
await setter(pref.key, pref.defaultValue);
}
/// This is a generic function to reset all preferences to their default values.
void resetAllPreferences() async =>
Future<void> resetAllPreferences() async {
PreferenceKeys.list.forEach(
// Necessary to avoid subtype erroneous type checking ¯\_(ツ)_/¯
(PreferenceKeys e) => (e) async {
await resetPreferences(e.key);
}
(PreferenceKeys e) async => await resetPreference(e.key)
);
}
Stream<int> get currentDesiredGPSAccuracy async* {
while (true) {
yield await getPreferencesInt(PreferenceKeys.GPS__ACCURACY.key);
await Future.delayed(Duration(milliseconds: 200));
}
}
}
\ No newline at end of file
......@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'package:device_preview/device_preview.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:logair_application/logic/handlers/network_handler.dart';
import 'package:logair_application/logic/handlers/preference_handler.dart';
import 'package:logair_application/ui/routes/home.dart';
import 'package:logair_application/localization/localization_delegate.dart';
......@@ -22,6 +24,9 @@ class LogAirApplication extends StatelessWidget {
@override
Widget build(BuildContext context) {
PreferencesHandler();
NetworkHandler();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
......
......@@ -11,7 +11,7 @@ class BatteryService {
int batteryLevel;
try {
batteryLevel = await methodChannel.invokeMethod('getBatteryLevel');
} on PlatformException catch (e) {
} on PlatformException {
batteryLevel = null;
}
yield batteryLevel;
......
import 'package:flutter/cupertino.dart';
import 'package:logair_application/logic/handlers/bluetooth_le_handler.dart';
class BTOverviewWidget extends StatelessWidget {
BTOverviewWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: BTLEHandler().isDeviceConnected(),
initialData: false,
builder: (context, snapshot) {
final bool value = snapshot.data;
if (value)
return Text("Connected");
else
return Text("Not connected");
},
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:logair_application/logic/handlers/database_handler.dart';
import 'package:logair_application/ui/animation/forward_animation.dart';
import 'package:logair_application/ui/components/body/overview/bt_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/db_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/map_position_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/network_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/overview_widgets/bt_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/overview_widgets/db_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/overview_widgets/map_position_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/overview_widgets/network_overview_widget.dart';
import 'package:logair_application/ui/components/body/overview/overview_navigation_button.dart';
import 'package:logair_application/ui/components/dialog/bluetooth_dialog/dialog.dart';
import 'package:logair_application/ui/components/header/header.dart';
import 'package:logair_application/ui/routes/preferences.dart';
import 'package:logair_application/logic/handlers/bluetooth_le_handler.dart';
import 'package:logair_application/logic/handlers/network_handler.dart';
import 'package:logair_application/ui/components/common/base_widget.dart';
......@@ -22,10 +18,7 @@ class OverviewWidget extends StatelessWidget {
width: double.infinity,
height: double.infinity,
alignment: Alignment.center,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
),
padding: EdgeInsets.all(6),
child: Container(
width: double.infinity,
height: double.infinity,
......@@ -33,8 +26,14 @@ class OverviewWidget extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.grey[400]
color: Colors.grey[200]
),
boxShadow: [
BoxShadow(
offset: Offset(2, -2),
color: Colors.grey[400]
)
],
color: Colors.grey[200],
),
child: child,
......@@ -92,16 +91,6 @@ class OverviewWidget extends StatelessWidget {
height: double.infinity,
child: Column(
children: [
/*
RaisedButton( onPressed: () => DatabaseHandler().data.then((value) => print(value.join("\n"))), child: Text('Print DB'), ),
RaisedButton( onPressed: () => DatabaseHandler().recreateDB(), child: Text('Delete DB'), ),
RaisedButton( onPressed: () => DatabaseHandler().getUnsent(20).then((value) => value.forEach(print)), child: Text('Print unsent'), ),
RaisedButton( onPressed: () => BTWakeHandler().switchState(), child: Text('Toggle BTLE Service'), ),
Spacer( flex: 1, ),
RaisedButton( onPressed: () => DataHandler().printLatest(), child: Text('Print Data Set'), ),
RaisedButton( onPressed: () => DataHandler().clearData(), child: Text('Clear Data'), ),
/// DEBUG END
Spacer( flex: 1, ),*/
Spacer(flex: 2),
/// Access the app settings
OverviewNavigationButton(
......
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logair_application/logic/data_header.dart';
import 'package:logair_application/ui/components/body/overview/overview_widgets/decorations.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class BTOverviewWidget extends StatelessWidget {
BTOverviewWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 50,
height: 50,
decoration: standardIconDecoration,
child: Icon(
Icons.bluetooth,
color: Colors.white,
size: 30,
),
),
Container(
decoration: standardDecoration,
padding: EdgeInsets.symmetric(vertical: 3, horizontal: 10),
margin: EdgeInsets.symmetric(horizontal: 5),
alignment: Alignment.center,
child: Column(
children: [
Text(
'Connected to',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 16
)
),
SizedBox(height: 5),
StreamBuilder<String>(
stream: DataHeader().deviceIdStream(),
initialData: '',
builder: (context, snapshot) => Text(
snapshot.data != '' ? snapshot.data : 'Unknown',
style: TextStyle(
color: Colors.white
)
)
)
],
),
),
Container(
decoration: standardDecoration,
padding: EdgeInsets.symmetric(vertical: 3, horizontal: 10),
margin: EdgeInsets.symmetric(horizontal: 5),
alignment: Alignment.center,
child: Column(
children: [
Text(
'Device battery',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 16
)
),
SizedBox(height: 5),
StreamBuilder<int>(
stream: DataHeader().deviceBatteryLevel(),
initialData: -1,
builder: (context, snapshot) {
int l = snapshot.data;
IconData icon;
if (l < 0) icon = MdiIcons.batteryUnknown;
else if (0 <= l && l <= 5) icon = MdiIcons.batteryAlertVariant;
else if (5 < l && l < 20) icon = MdiIcons.battery10;
else if (20 <= l && l < 30) icon = MdiIcons.battery20;
else if (30 <= l && l < 40) icon = MdiIcons.battery30;
else if (40 <= l && l < 50) icon = MdiIcons.battery40;
else if (50 <= l