[Flutter] Geolocator 사용하기

2023. 4. 3. 02:16Developers 공간 [Shorts]/Frontend

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

Map과 관련된 API중 자주 쓰이는 것은 사용자의 현재 GPS정보를 얻기위한 Geolocator와, Coordinate 정보를 활용해 주소를 얻어내거나 주소를 활용해 Coordinate정보를 얻어내는 Geocoder 등이 있습니다.

** 주의 : Geocoder는 장소의 이름을 검색하는 기능이 아니라, 주소와 Geo-Coordinate(latitude, longitude)사이의 변환입니다.

 

그 중 Geolocator를 Flutter에서 구현하기 위해 아래 패키지를 활용하려고 합니다.

https://pub.dev/packages/geolocator

 

페이지에 따르면 아래의 장점을 활용할 수 있습니다.

  • 가장 최근의 위치를 얻을 수 있습니다.
  • device의 현재 위치를 얻을 수 있습니다.
  • continuous하게 위치를 업데이트 할 수 있습니다.
  • 두개의 geocoordinate사이의 거리를 구할 수 있습니다.

2. Why? (원인)

  • X

3. How? (해결책)

  • Android 셋팅
    • android/gradle/gradle.properties : 아래가 되어있는지 확인합니다
      android.useAndroidX=true
      android.enableJetifier=true
    • android/app/build.gradle : 아래가 되어있는지 확인합니다
      android {
        compileSdkVersion 33
        ...
      }
    • android/app/src/main/AndroidManifest.xml : <manifest> 아래 <application>위에, 아래 두개 중에 하나를 추가합니다. CORASE는 city block 정도의 정확도를 보이며 FINE은 더 정확합니다. 두개 다 추가하는 경우 FINE이 쓰입니다.
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    • android/app/src/main/AndroidManifest.xml : Android 10 (SDK 버전 29)부터 아래를 추가해주어야, 앱이 background에서 동작할 때도 gps 정보를 update 받을 수 있습니다. CORASE에 지속적인 업데이트를 받는 경우 수 분의 시간 마다 받을 수 있습니다. 따라서 수 분내에 background에서 결과를 보장해야한다면 FINE을 권장합니다.
      ** Android 10은 Android Platform Version이며, 이에 해당하는 SDK API Level이 29 입니다.
      </uses-permission android:name="android.permission.access_background_location" >
  • iOS 셋팅
    •  ios/Runner/Info.plist : 아래의 key는 location에 접근하기 위해 기본적으로 필요한 권한입니다.
      <key>NSLocationWhenInUseUsageDescription</key>
      <string>{PRODUCT_NAME}이 location을 접근하기 위해 권한이 필요합니다.</string>
    •  ios/Runner/Info.plist : 아래의 key는 앱이 background에서 동작할 때도 gps 정보를 update 받을 수 있습니다. 하지만 이 권한을 사용하려면 open ios/Runner.xcworkspace 명령어를 통해 Project > Signing and Capabiities 에 들어가 아래 그림과 같이 "+Capability"를 눌러 "Background Modes"를 추가한 후 "Location Updates"를 선택해 줍니다.
      ** capability 를 추가하는 경우 App Store에 출시할 때 Apple에게 사유에 대해서 자세히 설명해야 거절당하지 않으므로, 참고해서 선택합니다.
      <key>NSLocationAlwaysUsageDescription</key>
      <string>{PRODUCT_NAME}이 지속적으로 location을 접근하기 위해 권한이 필요합니다.</string>
    • ios/Runner/Info.plist : iOS 14이상의 플랫폼에서 "일시적으로 정확한 location"을 얻기위해 requestTemporaryFullAccuracy({purposeKey: "YourPurposeKey1"})라는 함수를 사용하는 경우 아래의 key들을 추가해 줍니다. 아래 적는 "YourPurposeKey"는 어떤 목적인지에 따라 다르게 정보를 주기 위해 사용합니다.
      <key>NSLocationTemporaryUsageDescriptionDictionary</key>
      <dict>
        <key>YourPurposeKey1</key>
        <string>The example App requires temporary access to the device&apos;s precise location.</string>
        <key>YourPurposeKey2</key>
        <string>The example App requires temporary access to the device&apos;s precise location.</string>

      </dict>

[NSLocationAlwaysUsageDescription 사용시 Capability 추가 방법]

  • 구현 - 권한 요청
import 'package:geolocator/geolocator.dart';

Future<bool> _determinePermission() async {
	bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.value(false);
    }
    LocationPermission permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.value(false);
      }
    }
    if (permission == LocationPermission.deniedForever) {
      return Future.value(false);
    }
    return Future.value(true);
}
  • 구현 : GPS 정보 얻기
import 'package:geolocator/geolocator.dart';

Future<Position> _getPosition() async{
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best);

    return position;
}

_getPosition().then((position) {
      print("Template position check ${position.latitude}, ${position.longitude}");
}).onError((error, stackTrace) => null);

https://velog.io/@rlawnstn01023/XcodeInfo.plist-Privacy

728x90
반응형