잡동사니

반응형

질문

Flutter iOS 응용 프로그램에서 간단한지도 기능을 구현하려고합니다. 나는 Flutter 위치 패키지 readme 부터 중간"Flutter 앱에서 Google지도에 실시간 위치 업데이트 구현 "기사 , 유사한 문제에 관한 많은 스택 질문으로 끝납니다.

문제는지도를로드하기 전에 현재 위치를 가져올 수 없기 때문에 initialCameraPosition 에서 LatLng를 가져 오면 NPE가 발생한다는 것입니다. 내가 할 수있는 일은 하드 코딩 된 initialCameraPosition 으로지도를로드하는 것입니다. 그러면 현재 위치가 올바르게로드되고 드래그하거나 오른쪽 하단 모서리에있는 부동 위치 button을 클릭하여 카메라를 이동할 수 있습니다.

다음은 내 코드 샘플입니다.

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만 발생합니다.

currentLocation 이 null 일 때 빈 Container 를 반환하고 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 +0530Engine 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.3Java 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/DeveloperXcode 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/ContentsFlutter plugin version 45.0.1Dart plugin version 192.7761Java 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/ContentsFlutter extension version 3.9.1

[] Connected device (1 available)
    • iPhone 8F60856B8-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

답변1

FutureBuilder 가 작동하지만 과도하게 죽일 수 있다는 것을 깨닫는 초기 위치를 얻기 전에지도를 렌더링하는 문제입니다. 정말 필요한 것은 부울뿐입니다.

GoogleMapController mapController;
  LocationData currentLocation;
  Location location;
  bool _serviceEnabled;
  PermissionStatus _permissionGranted;
  CameraPosition _center =
      CameraPosition(target: SOURCE_LOCATION, zoom: CAMERA_ZOOM);
  bool isLoading = false;

  @override
  void initState() {
    super.initState();
    location = new Location();

    _getLocation();
  }

  _getLocation() async {
    setState(() {
      isLoading = true;
    });
    initialize();
    currentLocation = await location.getLocation();
    if (currentLocation == null) {
      return;
    }
    _center = CameraPosition(
        target: LatLng(currentLocation.latitude, currentLocation.longitude),
        zoom: CAMERA_ZOOM);

    setState(() {
      isLoading = false;
    });

    print("CurrentLocation: $currentLocation");
  }

  Future<void> initialize() 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;
      }
    }
  }

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.orangeAccent,
        title: Text('Map'),
        centerTitle: true,
      ),
      body: isLoading
          ? CircularProgressIndicator()
          : Container(
              child: GoogleMap(
                onMapCreated: _onMapCreated,
                initialCameraPosition: _center,
                myLocationEnabled: true,
              ),
            ),
    );
  }


답변2

대신 Geolocator 패키지를 사용하는 것이 좋습니다. 그것은 내가 위치를 얻고 위치를 구독하는 데 필요한 모든 앱에서 사용하는 것이며 잘 Document화되어 있습니다. 그것을 사용 해보고 해당 패키지로 FutureBuilder에 여전히 문제가있는 경우 새 코드로 게시물을 업데이트하면 추가로 도움을 드릴 수 있습니다.

FutureBuilder는지도가 빌드되기 전에 위치를 초기화하고 검색하지 않는 경우 갈 수있는 방법입니다.



 

 

 

 

출처 : https://stackoverflow.com/questions/61312809/flutter-ios-cannot-get-current-location-for-initialcameraposition-before-loadi

반응형

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band