Я пытаюсь реализовать простую функциональность карты в моем приложении Flutter iOS. Я следовал инструкциям, начиная с Readme пакета местоположения Flutter и до Среда "Внедрение обновлений местоположения в реальном времени на Google Maps в ваших приложениях Flutter" , заканчивая многими вопросами стека, касающимися подобных проблем.
Проблема в том, что я не могу получить текущее местоположение перед загрузкой карт, поэтому получение его LatLng в initialCameraPosition
приводит к NPE. Что я могу сделать, так это загружать карты жестко закодированным initialCameraPosition
, тогда текущее местоположение корректно загружается, и я могу перемещать камеру к нему, перетаскивая или нажимая кнопку плавающего местоположения в правом нижнем углу.
Здесь мой пример кода:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
const double CAMERA_ZOOM = 16;
const LatLng SOURCE_LOCATION = LatLng(37.3317, -122.0325086);
class MapPage extends StatefulWidget {
@override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
GoogleMapController mapController;
LocationData currentLocation;
Location location;
bool _serviceEnabled;
PermissionStatus _permissionGranted;
@override
void initState() {
super.initState();
location = new Location();
location.onLocationChanged.listen((event) {
currentLocation = event;
});
setInitialLocation();
}
void setInitialLocation() async {
_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
_serviceEnabled = await location.requestService();
if (!_serviceEnabled) {
return;
}
}
_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.granted) {
return;
}
}
currentLocation = await location.getLocation();
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
CameraPosition initialCameraPosition() {
LatLng target;
if (currentLocation != null)
target = LatLng(currentLocation.latitude, currentLocation.longitude);
else
target = SOURCE_LOCATION;
return CameraPosition(target: target, zoom: CAMERA_ZOOM);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.orangeAccent,
title: Text('Map'),
centerTitle: true,
),
body:
GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: initialCameraPosition(),
myLocationEnabled: true,
),
);
}
}
Я понимаю, что получение текущего местоположения является асинхронным процессом, поэтому я также попытался использовать FutureBuilder
в разделе тела:
FutureBuilder<LocationData>(
future: currentLocation,
builder: (context, snapshot) {
if (snapshot.hasData) {
LocationData currentLocation = snapshot.data;
return GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(
currentLocation.latitude, currentLocation.longitude)),
myLocationEnabled: true,
);
} else if (snapshot.hasError) {
return (Text("${snapshot.error}"));
}
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.orangeAccent,
),
);
},
),
, который работал как талисман, когда мне приходилось извлекать данные из HTTP-запроса GET, но на этот раз это приводит только к бесконечному CircularProgressIndicator
.
Я пробовал много других решений из вопросов стека, включая возврат пустого Container
, когда currentLocation
равно нулю, что создает условия для FutureBuilder snapshot.connectionState
, опять же безуспешно.
Забавно, что, когда я углубился в метод Location.getCurrentLocation()
, я нашел:
/// Gets the current location of the user.
///
/// Throws an error if the app has no permission to access location.
/// Returns a [LocationData] object.
Future<LocationData> getLocation() async {
return LocationPlatform.instance.getLocation();
}
который затем переходит к:
/// Gets the current location of the user.
///
/// Throws an error if the app has no permission to access location.
/// Returns a [LocationData] object.
Future<LocationData> getLocation() {
throw UnimplementedError();
}
, что ставит меня под сомнение, работает ли этот плагин вообще.
Вот мой flutter doctor -v
результат:
[✓] Flutter (Channel master, v1.18.0-6.0.pre.82, on Mac OS X 10.15.4 19E287, locale pl-PL)
• Flutter version 1.18.0-6.0.pre.82 at /Users/Vuco/flutter
• Framework revision f35b673f2b (26 hours ago), 2020-04-19 02:45:01 +0530
• Engine revision a5e0b2f2f2
• Dart version 2.9.0 (build 2.9.0-1.0.dev 5b19445d9c)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at /Users/Vuco/Library/Android/sdk
• Platform android-29, build-tools 29.0.3
• Java binary at: /Users/Vuco/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/192.6308749/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.4.1, Build version 11E503a
• CocoaPods version 1.9.1
[✓] Android Studio (version 3.6)
• Android Studio at /Users/Vuco/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/192.6308749/Android Studio.app/Contents
• Flutter plugin version 45.0.1
• Dart plugin version 192.7761
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
[!] IntelliJ IDEA Ultimate Edition (version 2020.1)
• IntelliJ at /Users/Vuco/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
• For information about installing plugins, see
https://flutter.dev/intellij-setup/#installing-the-plugins
[✓] VS Code (version 1.44.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.9.1
[✓] Connected device (1 available)
• iPhone 8 • F60856B8-2C6E-401D-A0F9-06FFC7E09876 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-4 (simulator)
! Doctor found issues in 1 category.
и зависимости, которые я использую:
google_maps_flutter: ^0.5.25+3
location: ^3.0.2