Add location permissions and implement real-time location updates on the map
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
|
||||||
<application
|
<application
|
||||||
android:label="travel_mate"
|
android:label="travel_mate"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ PODS:
|
|||||||
- GoogleMaps/Base (8.4.0)
|
- GoogleMaps/Base (8.4.0)
|
||||||
- GoogleMaps/Maps (8.4.0):
|
- GoogleMaps/Maps (8.4.0):
|
||||||
- GoogleMaps/Base
|
- GoogleMaps/Base
|
||||||
|
- location (0.0.1):
|
||||||
|
- Flutter
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
@@ -21,6 +23,7 @@ PODS:
|
|||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`)
|
- google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`)
|
||||||
|
- location (from `.symlinks/plugins/location/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
|
|
||||||
@@ -34,6 +37,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter
|
:path: Flutter
|
||||||
google_maps_flutter_ios:
|
google_maps_flutter_ios:
|
||||||
:path: ".symlinks/plugins/google_maps_flutter_ios/ios"
|
:path: ".symlinks/plugins/google_maps_flutter_ios/ios"
|
||||||
|
location:
|
||||||
|
:path: ".symlinks/plugins/location/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
@@ -44,6 +49,7 @@ SPEC CHECKSUMS:
|
|||||||
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
|
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
|
||||||
google_maps_flutter_ios: 0291eb2aa252298a769b04d075e4a9d747ff7264
|
google_maps_flutter_ios: 0291eb2aa252298a769b04d075e4a9d747ff7264
|
||||||
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
|
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
|
||||||
|
location: 155caecf9da4f280ab5fe4a55f94ceccfab838f8
|
||||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||||
|
|
||||||
|
|||||||
@@ -45,5 +45,9 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>We need your location to show it on the map.</string>
|
||||||
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||||
|
<string>We need your location to show it on the map even in background.</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
|
import 'package:location/location.dart';
|
||||||
|
|
||||||
class MapContent extends StatefulWidget {
|
class MapContent extends StatefulWidget {
|
||||||
const MapContent({super.key});
|
const MapContent({super.key});
|
||||||
@@ -9,7 +12,18 @@ class MapContent extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MapContentState extends State<MapContent> {
|
class _MapContentState extends State<MapContent> {
|
||||||
static LatLng _pGooglePlex = LatLng(50.64864814740268, 3.7224066213297293);
|
Location locationController = Location();
|
||||||
|
|
||||||
|
final Completer<GoogleMapController> _mapController =
|
||||||
|
Completer<GoogleMapController>();
|
||||||
|
|
||||||
|
LatLng? currentPosition;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
getLocationUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -21,7 +35,7 @@ class _MapContentState extends State<MapContent> {
|
|||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Rechercher un lieu',
|
hintText: 'Rechercher un lieu...',
|
||||||
prefixIcon: Icon(Icons.search),
|
prefixIcon: Icon(Icons.search),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
@@ -29,25 +43,91 @@ class _MapContentState extends State<MapContent> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 8.0),
|
SizedBox(height: 8.0),
|
||||||
Expanded(
|
SizedBox(
|
||||||
child: GoogleMap(
|
width: double.infinity,
|
||||||
initialCameraPosition: CameraPosition(
|
height: 50,
|
||||||
target: _pGooglePlex,
|
child: ElevatedButton(
|
||||||
zoom: 14.4746,
|
style: ElevatedButton.styleFrom(
|
||||||
),
|
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||||
markers: {
|
foregroundColor: Colors.white,
|
||||||
Marker(
|
shape: RoundedRectangleBorder(
|
||||||
markerId: MarkerId('googlePlex'),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
position: _pGooglePlex,
|
|
||||||
infoWindow: InfoWindow(title: 'Google Plex'),
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
// TODO : Logique de recherche à implémenter
|
||||||
},
|
},
|
||||||
|
child: Text('Chercher'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 8.0),
|
||||||
|
Expanded(
|
||||||
|
child: currentPosition == null
|
||||||
|
? const Center(child: Text("Chargement..."))
|
||||||
|
: GoogleMap(
|
||||||
|
onMapCreated: (GoogleMapController controller) =>
|
||||||
|
_mapController.complete(controller),
|
||||||
|
initialCameraPosition: CameraPosition(
|
||||||
|
target: currentPosition!,
|
||||||
|
zoom: 14.4746,
|
||||||
|
),
|
||||||
|
markers: {
|
||||||
|
Marker(
|
||||||
|
markerId: MarkerId('currentLocation'),
|
||||||
|
position: currentPosition!,
|
||||||
|
icon: BitmapDescriptor.defaultMarkerWithHue(
|
||||||
|
BitmapDescriptor.hueAzure,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _cameraToPosition(LatLng pos) async {
|
||||||
|
final GoogleMapController controller = await _mapController.future;
|
||||||
|
CameraPosition newCameraPosition = CameraPosition(target: pos, zoom: 13);
|
||||||
|
await controller.animateCamera(
|
||||||
|
CameraUpdate.newCameraPosition(newCameraPosition),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getLocationUpdate() async {
|
||||||
|
bool serviceEnabled;
|
||||||
|
PermissionStatus permissionGranted;
|
||||||
|
|
||||||
|
serviceEnabled = await locationController.serviceEnabled();
|
||||||
|
if (serviceEnabled) {
|
||||||
|
serviceEnabled = await locationController.requestService();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
permissionGranted = await locationController.hasPermission();
|
||||||
|
if (permissionGranted == PermissionStatus.denied) {
|
||||||
|
permissionGranted = await locationController.requestPermission();
|
||||||
|
if (permissionGranted != PermissionStatus.granted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locationController.onLocationChanged.listen((LocationData currentLocation) {
|
||||||
|
if (currentLocation.latitude != null &&
|
||||||
|
currentLocation.longitude != null) {
|
||||||
|
setState(() {
|
||||||
|
currentPosition = LatLng(
|
||||||
|
currentLocation.latitude!,
|
||||||
|
currentLocation.longitude!,
|
||||||
|
);
|
||||||
|
_cameraToPosition(currentPosition!);
|
||||||
|
print(currentPosition);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import location
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
48
pubspec.lock
48
pubspec.lock
@@ -176,6 +176,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.6"
|
version: "0.15.6"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.7"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -208,6 +224,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.1"
|
version: "5.1.1"
|
||||||
|
location:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: location
|
||||||
|
sha256: "06be54f682c9073cbfec3899eb9bc8ed90faa0e17735c9d9fa7fe426f5be1dd1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.3"
|
||||||
|
location_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: location_platform_interface
|
||||||
|
sha256: "8aa1d34eeecc979d7c9fe372931d84f6d2ebbd52226a54fe1620de6fdc0753b1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
|
location_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: location_web
|
||||||
|
sha256: ec484c66e8a4ff1ee5d044c203f4b6b71e3a0556a97b739a5bc9616de672412b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -445,6 +485,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.6"
|
version: "0.7.6"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ dependencies:
|
|||||||
shared_preferences: ^2.2.2
|
shared_preferences: ^2.2.2
|
||||||
path_provider: ^2.1.1
|
path_provider: ^2.1.1
|
||||||
bcrypt: ^1.1.3
|
bcrypt: ^1.1.3
|
||||||
|
location: ^5.0.0
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|||||||
Reference in New Issue
Block a user