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">
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
|
||||
<application
|
||||
android:label="travel_mate"
|
||||
android:name="${applicationName}"
|
||||
|
||||
@@ -11,6 +11,8 @@ PODS:
|
||||
- GoogleMaps/Base (8.4.0)
|
||||
- GoogleMaps/Maps (8.4.0):
|
||||
- GoogleMaps/Base
|
||||
- location (0.0.1):
|
||||
- Flutter
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
@@ -21,6 +23,7 @@ PODS:
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- 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`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
|
||||
@@ -34,6 +37,8 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter
|
||||
google_maps_flutter_ios:
|
||||
:path: ".symlinks/plugins/google_maps_flutter_ios/ios"
|
||||
location:
|
||||
:path: ".symlinks/plugins/location/ios"
|
||||
path_provider_foundation:
|
||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||
shared_preferences_foundation:
|
||||
@@ -44,6 +49,7 @@ SPEC CHECKSUMS:
|
||||
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
|
||||
google_maps_flutter_ios: 0291eb2aa252298a769b04d075e4a9d747ff7264
|
||||
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
|
||||
location: 155caecf9da4f280ab5fe4a55f94ceccfab838f8
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
|
||||
|
||||
@@ -45,5 +45,9 @@
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<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>
|
||||
</plist>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:location/location.dart';
|
||||
|
||||
class MapContent extends StatefulWidget {
|
||||
const MapContent({super.key});
|
||||
@@ -9,7 +12,18 @@ class MapContent extends StatefulWidget {
|
||||
}
|
||||
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
@@ -21,7 +35,7 @@ class _MapContentState extends State<MapContent> {
|
||||
children: [
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Rechercher un lieu',
|
||||
hintText: 'Rechercher un lieu...',
|
||||
prefixIcon: Icon(Icons.search),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
@@ -29,25 +43,91 @@ class _MapContentState extends State<MapContent> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8.0),
|
||||
Expanded(
|
||||
child: GoogleMap(
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: _pGooglePlex,
|
||||
zoom: 14.4746,
|
||||
),
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId('googlePlex'),
|
||||
position: _pGooglePlex,
|
||||
infoWindow: InfoWindow(title: 'Google Plex'),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
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 Foundation
|
||||
|
||||
import location
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
}
|
||||
|
||||
48
pubspec.lock
48
pubspec.lock
@@ -176,6 +176,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -208,6 +224,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -445,6 +485,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -34,6 +34,7 @@ dependencies:
|
||||
shared_preferences: ^2.2.2
|
||||
path_provider: ^2.1.1
|
||||
bcrypt: ^1.1.3
|
||||
location: ^5.0.0
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
|
||||
Reference in New Issue
Block a user