[flutter] 플러터 geolocator를 이용한 위치 기반 주문 및 배송 애플리케이션 개발 방법

이번 기술 블로그에서는 플러터 geolocator 패키지를 이용하여 위치 기반 주문 및 배송 애플리케이션을 개발하는 방법에 대해 알아보겠습니다.

목표

우리의 목표는 사용자의 현재 위치를 가져와 지정된 가게들과의 거리를 측정하고, 사용자가 원하는 상품을 주문 및 배달할 수 있는 애플리케이션을 개발하는 것입니다.

geolocator 패키지란?

geolocator는 플러터에서 제공하는 위치 정보를 가져오는 패키지입니다. 이 패키지를 이용하면 GPS, IP 주소 또는 플랫폼의 위치 서비스를 통해 사용자의 위치를 가져올 수 있습니다.

개발 절차

  1. geolocator 패키지 추가하기

    pubspec.yaml 파일에 geolocator 패키지를 추가합니다.

    dependencies:
      geolocator: ^7.0.3
    
  2. 퍼미션 설정하기

    안드로이드와 iOS에서 위치 정보에 접근하기 위해 권한을 허용해야 합니다.

    • 안드로이드: AndroidManifest.xml 파일에 다음 권한을 추가합니다.

      <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app">
        <!-- ... -->
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <!-- ... -->
      </manifest>
      
    • iOS: Info.plist 파일에 다음 권한을 추가합니다.

      <key>NSLocationWhenInUseUsageDescription</key>
      <string>Location permission is required to provide better user experience.</string>
      
  3. 위치 정보 가져오기

    geolocator 패키지를 이용하여 사용자의 위치 정보를 가져옵니다.

    import 'package:geolocator/geolocator.dart';
    
    class LocationService {
      Future<Position> getCurrentPosition() async {
        bool serviceEnabled;
        LocationPermission permission;
    
        // 위치 서비스 사용 가능 여부 체크
        serviceEnabled = await Geolocator.isLocationServiceEnabled();
        if (!serviceEnabled) {
          // 위치 서비스 사용 불가능할 경우 예외 처리
          throw Exception('Location service is disabled.');
        }
    
        // 위치 권한 요청
        permission = await Geolocator.checkPermission();
        if (permission == LocationPermission.deniedForever) {
          throw Exception('Location permissions are permanently denied, we cannot request permissions.');
        }
    
        if (permission == LocationPermission.denied) {
          // 위치 권한이 거부되었을 경우 권한 요청
          permission = await Geolocator.requestPermission();
          if (permission != LocationPermission.whileInUse && permission != LocationPermission.always) {
            throw Exception('Location permissions are denied.');
          }
        }
    
        // 위치 정보 가져오기
        return await Geolocator.getCurrentPosition();
      }
    }
    
  4. 거리 계산하기

    가져온 사용자의 위치와 가게들의 위치를 이용하여 거리를 계산합니다.

    import 'package:geolocator/geolocator.dart';
    
    class DistanceCalculator {
      double calculateDistance(double userLatitude, double userLongitude, double storeLatitude, double storeLongitude) {
        double distanceInMeters = Geolocator.distanceBetween(userLatitude, userLongitude, storeLatitude, storeLongitude);
        return distanceInMeters / 1000; // 거리를 킬로미터로 변환하여 반환
      }
    }
    
  5. 애플리케이션 구현하기

    위의 코드들을 이용하여 주문 및 배송 애플리케이션을 구현합니다. 사용자의 위치를 가져오고, 가게들의 위치와 거리를 계산하여 주문과 배송을 처리하는 기능을 추가합니다.

    import 'package:flutter/material.dart';
    import 'package:geolocator/geolocator.dart';
    
    class OrderDeliveryApp extends StatefulWidget {
      @override
      _OrderDeliveryAppState createState() => _OrderDeliveryAppState();
    }
    
    class _OrderDeliveryAppState extends State<OrderDeliveryApp> {
      Position _userPosition;
    
      @override
      void initState() {
        super.initState();
        _getUserLocation();
      }
    
      Future<void> _getUserLocation() async {
        try {
          Position position = await LocationService().getCurrentPosition();
          setState(() {
            _userPosition = position;
          });
        } catch (e) {
          // 위치 정보 가져오기 실패 처리
          print('Failed to get user location: $e');
        }
      }
    
      double _calculateStoreDistance(double storeLatitude, double storeLongitude) {
        if (_userPosition != null) {
          double distance = DistanceCalculator().calculateDistance(
            _userPosition.latitude,
            _userPosition.longitude,
            storeLatitude,
            storeLongitude,
          );
          return distance;
        }
        return null;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Order Delivery App'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                if (_userPosition != null)
                  Text('Your current location: ${_userPosition.latitude}, ${_userPosition.longitude}'),
                SizedBox(height: 20),
                Text('Store A distance: ${_calculateStoreDistance(37.123, 126.456)} km'),
                SizedBox(height: 10),
                Text('Store B distance: ${_calculateStoreDistance(37.789, 127.012)} km'),
              ],
            ),
          ),
        );
      }
    }
    

    이제 애플리케이션에서 사용자의 위치를 가져오고, 가게들과의 거리를 계산하여 출력합니다.

결론

이제 플러터 geolocator 패키지를 이용하여 위치 기반 주문 및 배송 애플리케이션을 개발할 수 있는 방법에 대해 알아보았습니다. 이를 기반으로 더욱 복잡한 기능을 추가하여 실제 애플리케이션을 개발해보세요.

참고 자료