Commit 96b3ac5f authored by CLOUARD Regis's avatar CLOUARD Regis
Browse files

18 add nfc and gps permissions in mode choice

parent 2eb52068
......@@ -17,7 +17,7 @@ un code QR et tag NFC. Un mode automatique permet de faire la validation des poi
directement à partir de la position GPS sans utiliser les codes QR ou les tags NFC.
L’orienteur utilise l’application pour se repérer à partir de la carte et valider son passage
aux points de contrôle avec le lecteur de code QR ou le lecteur de tag NFC ou la position GPS.
aux points de contrôle avec le lecteur de code QR, le lecteur de tag NFC ou la position GPS.
L’application affiche en fin du parcours des statistiques sur la réalisation du parcours :
le temps total, le temps intermédiaire entre chaque balise et le tracé du parcours réalisé.
......
......@@ -34,8 +34,8 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "fr.ensicaen.ecole.vikazimut"
minSdkVersion 16
targetSdkVersion 28
minSdkVersion 23
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
......
{
"app_name":"Vikazimut",
"action_settings":"Allow",
"action_not_settings":"Deny",
"nfc_disabled_message":"The NFC reader is disabled. Do you want to enable it and using it instead of the QR Code reader?",
"allow_gps_service":"Allow",
"deny_gps_service":"Deny",
"enable_gps_service":"Enable",
"disable_gps_service":"Disable",
"nfc_disabled_message":"The NFC reader is disabled. Do you want to enable it?",
"nfc_unavailable_message":"This device does not have NFC support.\nYou will need to validate the control points with the QR Code reader or the GPS location.",
"gps_disabled_message":"The GPS service is disabled. Do you want to enable it?",
"gps_unavailable_message":"This device does not have GPS support.\nSorry, Vikazimut cannot be used without geolocation.",
"gps_disabled_message":"The location service is disabled and is needed.\nDo you want to enable it?",
"gps_denied_message":"Vikazimut has no permission to use location.\nAllow Vikazimut to access this device's location?",
"qr_code_menu_item":"Flash the QR Code",
"course_state_message":"Validated control point",
"ok":"OK",
......
{
"app_name":"Vikazimut",
"action_settings":"Activer",
"action_not_settings":"Refuser",
"nfc_disabled_message":"Le lecteur NFC est désactivé. Voulez-vous l'activer et l'utiliser à la place du lecteur de code QR\u00A0?",
"allow_gps_service":"Autoriser",
"deny_gps_service":"Refuser",
"enable_gps_service":"Activer",
"disable_gps_service":"Refuser",
"nfc_disabled_message":"Le lecteur NFC est désactivé. Voulez-vous l'activer\u00A0?",
"nfc_unavailable_message":"Votre appareil ne possède pas de lecteur NFC.\nVous devrez valider les postes avec le lecteur de code QR ou avec la localisation GPS.",
"gps_disabled_message":"La fonction GPS de votre appareil est désactivée. Voulez-vous l'activer\u00A0?",
"gps_unavailable_message":"Votre appareil ne possède pas de fonction GPS.\nDésolé, Vikazimut ne peut pas être utilisée sans la géolocalisation.",
"gps_disabled_message":"La fonction localisation de votre appareil est désactivée.\nVoulez-vous l'activer\u00A0?",
"gps_denied_message":"L'application n'a pas l'autorisation d'utiliser le GPS. Voulez-vous l'autoriser\u00A0?",
"no_network_and_no_stored_map_error_message":"Pas de connexion réseau et aucune carte préalablement enregistrée.\nImpossible de continuer.",
"network_but_no_stored_map_error_message":"Pas de carte disponible actuellement sur le serveur.\nImpossible de continuer.",
"error_creating_directory":"Erreur système. Impossible de créer le dossier des images\u00A0: %s",
......
......@@ -49,7 +49,7 @@ StreamSubscription<Position> positionStream = Geolocator.getPositionStream(locat
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: new Text("Course Page"), actions: <Widget>[
appBar: AppBar(title: new Text("0:00:00"), actions: <Widget>[
IconButton(
icon: const Icon(Icons.device_hub),
tooltip: 'Code QR',
......@@ -170,14 +170,11 @@ class MapPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var paint = new Paint();
// static double _computeImageScale( int width, int height, int leftBound, int topBound, int rightBound, int bottomBound ) {
// int boundWidth = rightBound - leftBound;
// int boundHeight = bottomBound - topBound;
// return Math.min(boundWidth / (double) width, boundHeight / (double) height);
// }
var scale = size.width / image.width;
var vScale = size.width / image.width;
var hScale = size.height / image.height;
var scale = min(vScale, hScale);
canvas.translate((size.width - image.width * scale)/2.0, (size.height - image.height * scale) / 2.0);
canvas.scale(scale * zoom);
canvas.translate(image.width / 2 * scale, image.height / 2 * scale);
canvas.drawImage(image, offset, paint);
}
......
......@@ -129,13 +129,7 @@
// return translation + bottom > limit;
// }
// }
//
// static double _computeImageScale( int width, int height, int leftBound, int topBound, int rightBound, int bottomBound ) {
// int boundWidth = rightBound - leftBound;
// int boundHeight = bottomBound - topBound;
// return Math.min(boundWidth / (double) width, boundHeight / (double) height);
// }
//
///
// static int[] _convertGeoPointIntoMapCoordinates( double latitude, double longitude, LatLonBox boundingBox, int imageWidth, int imageHeight ) {
// int x = (int) ((longitude - boundingBox.west) * imageWidth / (boundingBox.east - boundingBox.west));
// int y = (int) ((latitude - boundingBox.north) * imageHeight / (boundingBox.south - boundingBox.north));
......
......@@ -9,6 +9,7 @@ import 'package:Vikazimut_flutter/course/sport_mode_course_widget.dart';
import 'package:Vikazimut_flutter/map/orienteering_map_factory.dart';
import 'package:Vikazimut_flutter/map_choice/map_choice.dart';
import 'package:Vikazimut_flutter/map_choice/map_proxy.dart';
import 'package:Vikazimut_flutter/utils/alert_dialog.dart';
import 'package:disk_space/disk_space.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
......@@ -369,89 +370,6 @@ int _getFileFolderSize(String directoryPath) {
return totalSize;
}
showErrorDialog(BuildContext context, {String title, String message}) {
Widget okButton = FlatButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
// launchMissile();
},
);
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
actions: [
okButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
showAlertDialog2Buttons(BuildContext context) {
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget continueButton = FlatButton(
child: Text("Continue"),
onPressed: () {},
);
AlertDialog alert = AlertDialog(
title: Text("AlertDialog"),
content: Text("Would you like to continue learning how to use Flutter alerts?"),
actions: [
cancelButton,
continueButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
showAlertDialog3buttons(BuildContext context) {
Widget remindButton = FlatButton(
child: Text("Remind me later"),
onPressed: () {},
);
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget launchButton = FlatButton(
child: Text("Launch missile"),
onPressed: () {},
);
AlertDialog alert = AlertDialog(
title: Text("Notice"),
content: Text("Launching this missile will destroy the entire universe. Is this what you intended to do?"),
actions: [
remindButton,
cancelButton,
launchButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
void updateAfterMapDownloadSuccess(MapProxy mapProxy) {
if (mapProxy != null) {
mapProxy.setDownloaded(true);
......
......@@ -5,42 +5,31 @@ import 'package:Vikazimut_flutter/help/GeneralConditionsOfUse.dart';
import 'package:Vikazimut_flutter/help/UserManual.dart';
import 'package:Vikazimut_flutter/history/History.dart';
import 'package:Vikazimut_flutter/map_choice/map_choice.dart';
import 'package:Vikazimut_flutter/utils/alert_dialog.dart';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:package_info/package_info.dart';
import 'package:url_launcher/url_launcher.dart';
class ModeChoice extends StatefulWidget {
// STATELESS ?
@override
_ModeChoiceState createState() => _ModeChoiceState();
}
class _ModeChoiceState extends State<ModeChoice> {
String _versionNumber = "";
@override
void initState() {
super.initState();
_getVersionNumber();
WidgetsBinding.instance.addPostFrameCallback((_) {
checkGeolocationPermission();
});
}
/*
TODO
import 'package:geolocator/geolocator.dart';
LocationPermission permission = await Geolocator.checkPermission();
LocationPermission permission = await Geolocator.requestPermission();
Possible results from the checkPermission and requestPermission methods are:
Permission Description
denied Permission to access the device's location is denied by the user. You are free to request permission again (this is also the initial permission state).
deniedForever Android only: Permission to access the device's location is denied forever. If requesting permission the permission dialog will NOT been shown until the user updates the permission in the App settings.
whileInUse Permission to access the device's location is allowed only while the App is in use.
always Permission to access the device's location is allowed even when the App is running in the background.
*/
@override
Widget build(BuildContext context) {
return Scaffold(
......@@ -103,6 +92,9 @@ always Permission to access the device's location is allowed even when the App i
],
onSelected: (value) async {
switch (value) {
case 1:
resetParameters();
break;
case 2:
Navigator.push(context, MaterialPageRoute(builder: (context) => UserManual()));
break;
......@@ -126,10 +118,11 @@ always Permission to access the device's location is allowed even when the App i
splashColor: Colors.orangeAccent,
padding: EdgeInsets.all(10.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MapChoice(CourseMode.SPORT)),
);
checkGeolocationActivation().then((value) {
if (value) {
Navigator.push(context, MaterialPageRoute(builder: (context) => MapChoice(CourseMode.SPORT)));
}
});
},
child: Column(
// TODO Faire une widget generique avec des paramètres.
......@@ -184,10 +177,11 @@ always Permission to access the device's location is allowed even when the App i
splashColor: Colors.orangeAccent,
padding: EdgeInsets.all(10.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MapChoice(CourseMode.WALK)),
);
checkGeolocationActivation().then((value) {
if (value) {
Navigator.push(context, MaterialPageRoute(builder: (context) => MapChoice(CourseMode.SPORT)));
}
});
},
child: Column(
mainAxisSize: MainAxisSize.min,
......@@ -280,6 +274,52 @@ always Permission to access the device's location is allowed even when the App i
throw 'Could not launch $url'; // TODO multilingue + alertDialog
}
}
void checkGeolocationPermission() async {
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.deniedForever || permission == LocationPermission.denied) {
showErrorDialog(
context,
title: Translations.of(context).getString("location_required_tile"),
message: Translations.of(context).getString("impossible_without_location_provider"),
);
}
}
}
Future<bool> checkGeolocationActivation() async {
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
showAlertDialog2Buttons(
context,
title: Translations.of(context).getString("warning_title"),
message: Translations.of(context).getString("gps_denied_message"),
yesButtonText: Translations.of(context).getString("allow_gps_service"),
noButtonText: Translations.of(context).getString("deny_gps_service"),
yesAction: () => Geolocator.openAppSettings(),
);
return false;
}
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
showAlertDialog2Buttons(
context,
title: Translations.of(context).getString("warning_title"),
message: Translations.of(context).getString("gps_disabled_message"),
yesButtonText: Translations.of(context).getString("enable_gps_service"),
noButtonText: Translations.of(context).getString("disable_gps_service"),
yesAction: () => Geolocator.openLocationSettings(),
);
return false;
}
return true;
}
void resetParameters() {
Geolocator.openAppSettings();
}
}
class VersionNumberTextWidget extends StatelessWidget {
......
import 'package:flutter/material.dart';
showErrorDialog(BuildContext context, {String title, String message, void Function() action = null}) {
Widget okButton = FlatButton(
child: Text("OK"),
onPressed: () {
if (action != null) {
action();
}
Navigator.of(context).pop();
},
);
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
actions: [
okButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
showAlertDialog2Buttons(BuildContext context, {String title, String message, String yesButtonText, String noButtonText, void Function() yesAction = null, void Function() noAction = null}) {
// TODO Make ity uncancelable
Widget noButton = FlatButton(
child: Text(noButtonText),
onPressed: () {
if (noAction != null) noAction();
Navigator.of(context).pop();
},
);
Widget yesButton = FlatButton(
child: Text(yesButtonText),
onPressed: () {
if (yesAction != null) yesAction();
Navigator.of(context).pop();
},
);
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
actions: [
noButton,
yesButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
showAlertDialog3buttons(BuildContext context) {
Widget remindButton = FlatButton(
child: Text("Remind me later"),
onPressed: () {},
);
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget launchButton = FlatButton(
child: Text("Launch missile"),
onPressed: () {},
);
AlertDialog alert = AlertDialog(
title: Text("Notice"),
content: Text("Launching this missile will destroy the entire universe. Is this what you intended to do?"),
actions: [
remindButton,
cancelButton,
launchButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
......@@ -129,7 +129,7 @@ packages:
name: flutter_native_splash
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "1.1.1+1"
flutter_test:
dependency: "direct dev"
description: flutter
......@@ -424,7 +424,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.4"
xdg_directories:
dependency: transitive
description:
......@@ -447,5 +447,5 @@ packages:
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.12.0-259.9.beta <3.0.0"
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.22.0"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment