使用 geolocator 和 provider 以及 flutter_maps 获取位置

Posted

技术标签:

【中文标题】使用 geolocator 和 provider 以及 flutter_maps 获取位置【英文标题】:get location with geolocator and provider and flutter_maps 【发布时间】:2020-07-28 07:52:51 【问题描述】:

我正在尝试使用地理定位器插件获取用户当前位置,并且我正在使用提供程序包来处理状态。但我收到“初始位置为空”错误消息。我使用的是 flutter_maps 包,而不是谷歌地图。

我尝试使用提供程序包寻找解决方案,但没有找到。

这是我的代码:

main.dart:

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';

import './maps_module/map_states.dart';
import 'home_page.dart';


void main() 
  WidgetsFlutterBinding.ensureInitialized();
  return runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: AppState())
      ],
      child: MyApp(),
    )
  );


class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  

home_page.dart:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:latlong/latlong.dart';
import 'package:geolocator/geolocator.dart';

import './maps_module/map_states.dart';
import './maps_module/maps_screen.dart';


class HomePage extends StatelessWidget 

  @override
  Widget build(BuildContext context) 

    final appState = Provider.of<AppState>(context);

    return Scaffold(
      body: appState.initialPosition == null?
      Center(
        child: CircularProgressIndicator(),
      )
      :MapScreen(),
    );
  

map_screen.dart:

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';

import 'map_states.dart';


class MapScreen extends StatefulWidget 
  @override
  _MapScreenState createState() => new _MapScreenState();


class _MapScreenState extends State<MapScreen> 

  @override
  Widget build(BuildContext context) 

    final appState = Provider.of<AppState>(context);

    return SafeArea(
      child: Scaffold(
        // appBar: AppBar(),
        body: FlutterMap(
          mapController: appState.mapController,
          options: MapOptions(
            center: LatLng(appState.initialPosition.latitude, appState.initialPosition.longitude),
            minZoom: 10.0
          ),
          layers: [
            TileLayerOptions(
              urlTemplate: "https://s.tile.openstreetmap.org/z/x/y.png",
              subdomains: ['a','b','c']
            ),
            MarkerLayerOptions(
              markers: [
                Marker(
                  width: 80.0,
                  height: 80.0,
                  point: appState.initialPosition,
                  builder: (context) =>
                  Container(
                    child: IconButton(
                      icon: Icon(Icons.location_on),
                      color: Colors.redAccent,
                      iconSize: 45.0,
                      onPressed: ()print("hey");
                    ),
                  )
                )
              ]
            )
          ],
        ),
      )
    );
  

地图状态:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';


class AppState with ChangeNotifier 

  bool locationServiceActive = true;

  MapController _mapController;
  MapController get mapController => _mapController;

  static var _initialPosition;
  var _lastPosition = _initialPosition;
  LatLng get initialPosition => _initialPosition;
  LatLng get lastPosition => _lastPosition;

  AppState()
    checkGPS();
    _getUserLocation();
  


  checkGPS() async
    bool conn = await Geolocator().isLocationServiceEnabled();
    if(conn == false)
      locationServiceActive = false;
     else 
      locationServiceActive = true;
    
    notifyListeners();
  

  void _getUserLocation() async
    Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    print("/////////////////////////////////////////////////////////////////////////////////position");
    print(position);

    _initialPosition = LatLng(position.latitude, position.longitude);
    notifyListeners();
  

【问题讨论】:

【参考方案1】:

你的问题是你需要在你的类构造函数中awaitcheckgps()_getUserLocation()问题是你不能从类的构造函数运行异步函数所以你需要做这样的事情.首先,您需要从 _getUserLocation() 中删除 void 或将其设为 Future&lt;void&gt; 然后添加。

//Add to your class 
initalization() async 
    await _checkGPS();
    await getUserLocation();
  

//This in a widget will prove it works
 @override
  void initState() 
    AppState().initalization();
    print('Location $AppState().initialPosition');
    super.initState();
  

【讨论】:

这个方法没用,当然感谢你的帮助...

以上是关于使用 geolocator 和 provider 以及 flutter_maps 获取位置的主要内容,如果未能解决你的问题,请参考以下文章

如果在同一页面中使用 navigator.geolocation.getCurrentPosition 和 navigator.geolocation.watchPosition 将不起作用

在 Map 和 navigator.geolocation 上使用 Leaflet 的多个事件

使用 navigator.geolocation 获取地理位置

使用 navigator.geolocation.watchPosition 的 javascript 对象变量和方法范围问题

如何使用 GeoLocation 在地图上定位标记?

使用 Geolocation 和 Google Maps API [帮助]