인프런 커뮤니티 질문&답변

kut7728님의 프로필 이미지
kut7728

작성한 질문수

[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

코드 정리하기

Appbar 의 my_location 버튼을 눌러도 현재위치로 이동하질 않습니다.

작성

·

44

0

강의 정말 잘 듣고있습니다!

 

오늘도 출근 프로젝트에서 앱바 액션 버튼의

현재 위치로 시점 이동 버튼 기능이 동작하지 않습니다.

 

중간에 기능 확인할때 잘 작동하는것을 확인했는데

강의 다 듣고 나서 다시 확인하니 작동을 하지 않습니다.

 

Geolocator.getCurrentPosition() 여기서 데이터를 못받아와서 그런것 같은데 뭐 때문에 갑자기 못 받아오는건지 알수가 없습니다...

 

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final CameraPosition initialPosition = CameraPosition(
      target: LatLng(
        37.5214,
        126.9246,
      ),
      zoom: 15);

  late final GoogleMapController controller;

  bool choolCheckDone = false;
  bool canChoolCheck = false;
  final double okDistance = 100;
  final testPosition = LatLng(37.5214, 126.9246);

  @override
  initState() {
    super.initState();

    Geolocator.getPositionStream().listen((event) {
      final start = testPosition;
      final end = LatLng(event.latitude, event.longitude);

      final distance = Geolocator.distanceBetween(
        start.latitude,
        start.longitude,
        end.latitude,
        end.longitude,
      );

      setState(() {
        if (distance > okDistance) {
          canChoolCheck = false;
        } else {
          canChoolCheck = true;
        }
      });
    });
  }

  checkPermission() async {
    final isLocationEnabled = await Geolocator.isLocationServiceEnabled();

    if (!isLocationEnabled) {
      throw Exception('위치 기능을 활성화 해주세요.');
    }

    LocationPermission checkedPermission = await Geolocator.checkPermission();

    if (checkedPermission == LocationPermission.denied) {
      checkedPermission = await Geolocator.requestPermission();
    }

    if (checkedPermission != LocationPermission.always &&
        checkedPermission != LocationPermission.whileInUse) {
      throw Exception('위치 권한을 허용 해주세요.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          '오늘도 출근',
          style: TextStyle(
            color: Colors.blue,
            fontWeight: FontWeight.w700,
          ),
        ),
        actions: [
          IconButton(
            color: Colors.blue,
            onPressed: myLocationPressed,
            icon: Icon(Icons.my_location),
          ),
        ],
      ),
      body: FutureBuilder(
        future: checkPermission(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasError) {
            return Center(
              child: Text(snapshot.error.toString()),
            );
          }
          return Column(
            children: [
              Expanded(
                flex: 2,
                child: _GoogleMaps(
                  testPosition: testPosition,
                  okDistance: okDistance,
                  canChoolCheck: canChoolCheck,
                  initialPosition: initialPosition,
                  onMapCreated: googleMapController,
                ),
              ),
              Expanded(
                flex: 1,
                child: _Bottom(
                  choolCheckDone: choolCheckDone,
                  canChoolCheck: canChoolCheck,
                  onChoolCheckPressed: onChoolCheckPressed,
                ),
              )
            ],
          );
        },
      ),
    );
  }

  googleMapController(GoogleMapController controller) {
    // state에 선언한 controller에 방금 선언한 controller 넣음
    this.controller = controller;
  }

  onChoolCheckPressed() async {
    final result = await showDialog(
      context: context,
      builder: (BuildContext context) {
        return CupertinoAlertDialog(
          title: Text('출근하기'),
          content: Text('출근을 하시겠습니까?'),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop(false);
              },
              child: Text('취소'),
              style: TextButton.styleFrom(foregroundColor: Colors.red),
            ),
            TextButton(
              onPressed: () {
                Navigator.of(context).pop(true);
              },
              child: Text('출근하기'),
              style: TextButton.styleFrom(foregroundColor: Colors.blue),
            )
          ],
        );
      },
    );

    if (result) {
      setState(() {
        choolCheckDone = true;
      });
    }
  }

  myLocationPressed() async {
    print('before');
    final location = await Geolocator.getCurrentPosition();
    print('after');



    controller.animateCamera(
      CameraUpdate.newLatLng(
        // 이 위치로 구글맵 카메라를 애니메이션과 함께 움직여라!
        LatLng(
          location.latitude,
          location.longitude,
        ),
      ),
    );
  }
}

class _GoogleMaps extends StatelessWidget {
  final LatLng testPosition;
  final double okDistance;
  final bool canChoolCheck;
  final CameraPosition initialPosition;
  final MapCreatedCallback onMapCreated;

  const _GoogleMaps({
    super.key,
    required this.testPosition,
    required this.okDistance,
    required this.canChoolCheck,
    required this.initialPosition,
    required this.onMapCreated,
  });

  @override
  Widget build(BuildContext context) {
    return GoogleMap(
      initialCameraPosition: initialPosition,
      mapType: MapType.normal,
      myLocationEnabled: true,
      myLocationButtonEnabled: false,
      zoomControlsEnabled: false,
      onMapCreated: onMapCreated,
      markers: {
        Marker(
          markerId: MarkerId('123'),
          position: testPosition,
        ),
      },
      circles: {
        Circle(
          circleId: CircleId('inDistance'),
          center: testPosition,
          radius: okDistance,
          fillColor: canChoolCheck
              ? Colors.blue.withOpacity(0.5)
              : Colors.red.withOpacity(0.5),
          strokeColor: canChoolCheck ? Colors.blue : Colors.red,
          strokeWidth: 1,
        )
      },
    );
  }
}

class _Bottom extends StatelessWidget {
  final bool choolCheckDone;
  final bool canChoolCheck;
  final VoidCallback onChoolCheckPressed;

  const _Bottom({
    super.key,
    required this.choolCheckDone,
    required this.canChoolCheck,
    required this.onChoolCheckPressed,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Icon(
          choolCheckDone ? Icons.check : Icons.timelapse_outlined,
          color: choolCheckDone ? Colors.green : Colors.blue,
        ),
        SizedBox(
          height: 16,
        ),
        if (!choolCheckDone && canChoolCheck)
          OutlinedButton(
            onPressed: onChoolCheckPressed,
            child: Text('출근하기'),
            style: OutlinedButton.styleFrom(
              foregroundColor: Colors.blue,
            ),
          ),
      ],
    );
  }
}

답변 2

0

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

안녕하세요!

함수 실행이 멈춘다는 뜻일까요 아니면 에러를 던진다는 뜻일까요 아니면 잘못된 좌표가 반환된다는 뜻일까요?

감사합니다!

kut7728님의 프로필 이미지
kut7728
질문자

함수 실행이 멈춘다는게 맞는것 같습니다.

myLocationPressed() async {
    print('before');
    final location = await Geolocator.getCurrentPosition();
    print('after');

myLocationPressed 함수가 실행됐을때 before 까지만 프린트되고 아무 반응이 없더라구요.

 

 

 

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

혹시 권한 문제가 있는건 아닌가요? 세팅에 가서 권한이 열려있는지 확인 해주세요!

0

안녕하세요, 인프런 AI 인턴입니다. kut7728님의 질문에 답변드립니다.

질문 내용을 바탕으로 본다면, Geolocator.getCurrentPosition() 호출 시 현재 위치 정보를 가져오지 못하는 문제와 관련된 이슈로 보입니다. 동일한 주제에 관해 이전에 다른 수강생이 질문한 내용과 유사하거나 관련성이 높은 답변을 찾았습니다.

  1. iOS 시뮬레이터 위치이동이 안됩니다 - iOS 시뮬레이터 위치이동이 안됩니다 질문 링크

    • 이 질문에서는 iOS 시뮬레이터에서 위치이동이 안되는 문제에 대해 다루고 있습니다. 작성된 답변에 따르면, iOS 시뮬레이터에서 일부 버그가 있을 수 있으며 실제 배포 시에는 문제가 없으므로, 안드로이드 에뮬레이터에서 잘 작동되면 로직에는 문제가 없다는 점을 지적합니다.
  2. 섹션 15. iPhone Simulator & Geolocator 오류 - 섹션 15. iPhone Simulator & Geolocator 오류 질문 링크

    • 이 질문에서는 특정 섹션 내의 iPhone Simulator와 Geolocator 관련 오류에 대해 언급되었습니다. 해당 답변에서도 iOS 시뮬레이터에서 생기는 현상으로 파악되며 실제 배포 시에는 문제 없음을 언급합니다.

위의 질문과 답변을 참고하시면 유사한 문제를 겪고 계신다면 해결 방향을 얻을 수도 있습니다. 그러나 문제가 계속 발생한다면 다음과 같은 추가 조치를 고려해 볼 수 있습니다:
- 위치 권한 확인: 위치 기능이 활성화되어 있고, 앱에 필요한 위치 권한(항상 허용, 앱 사용 중 허용)이 있는지 확인하세요.
- 디바이스 및 시뮬레이터 재시작: 가끔은 기기나 시뮬레이터를 재시작하는 것만으로도 문제가 해결되는 경우가 있습니다.
- Geolocator 패키지 버전: 패키지의 버전이 최신인지 확인하고, 필요하다면 업데이트를 고려해 보세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

kut7728님의 프로필 이미지
kut7728

작성한 질문수

질문하기