LoginSignup
38
30

More than 3 years have passed since last update.

[Flutter] Geolocatorを使用して現在位置情報を取得する方法

Posted at

概要

Flutterを運用して5ヶ月が経ちました。
3ヶ月前から弊社ではFlutterが普及しだし、エンジニア4人が全てFlutterをかけるようになってきました。現在は自社アプリの新機能追加とアーキテクチャの導入を頑張っているという感じです。

今回は自社アプリで位置情報を取得する必要があったので、何かライブラリないかなと調べてみたら良さげなものがあったのと、導入にちょっと時間がかかったのと、単純に現在位置だけを返すだけのソースコードがあまりなかったのでその共有をします。

今回やること

iOS実機で現在位置情報を 緯度(Latitude) 経度(Longitude) で取得する(Androidはライブラリ通りでうまくいくので特に記載はしない)

環境

iPhone/iOS

iPhone XR 12.4

Flutter

Flutter 1.9.1
Dart 2.3.0

ライブラリ

geolocator 5.1.3

導入

1. pubspec.yaml に記載してpub get

お約束ですね

pudspec.yaml
 dependencies:
    geolocator: ^5.1.3

2. ios/Runner/info.plist にpermissionを記載する

iOS doesn't ask for Location permissionsで記載されているエラーが発生しているので、どうも info.plist に記載する必要があるっぽいので以下のように編集します。

info.plist
...
<dict>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Your location is required for this app</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Your location is required for this app</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Your location is required for this app</string>
...
</dict>

3. 実装してみる

location.dart
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

class LocationSample extends StatefulWidget{
  @override
  _LocationSampleState createState() => _LocationSampleState();
}

class _LocationSampleState extends State<LocationSample> {
  // Location
  Position position; // Geolocator

  @override
  void initState() {
    super.initState();
    _getLocation(context);
  }

  Future<void> _getLocation(context) async {
    Position _currentPosition = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high); // ここで精度を「high」に指定している
    print(_currentPosition);
    setState(() {
      position = _currentPosition;
    });
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<GeolocationStatus>(
      future: Geolocator().checkGeolocationPermissionStatus(),
      builder: 
          (BuildContext context, AsyncSnapshot<GeolocationStatus> snapshot) {
        if (!snapshot.hasData) {
          return const Center(child: CircularProgressIndicator());
        }

        if (snapshot.data == GeolocationStatus.denied) {
          return Text(
            'Access to location denied',
            textAlign: TextAlign.center,
          );
        }

        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(
                "Location Infomation",
                style: TextStyle(
                  fontSize: 20.0
                ),
              ),
              Text("Your Current Location is :"),
              Text("${position}")
            ],
          ),
        );
      }
    );
  }
}

4. 結果

  • Permission

最初にiOSの位置情報のPermissionの処理が走ります。とりあえず「このAppの使用中のみ許可」を選択しましょう。

  • Loading

許可を選択すると、位置情報の取得に数秒時間がかかります。ここではnull値が入ってきています。

  • Current Location

数秒後、無事現在位置が取得し、null値がLat(Latitude)とLong(Longitude)に書き換わりました。(表示されているのはオフィス周辺の情報)
その後、数秒後ごとに現在位置を取得し、返してくれるようになりました。
ライブラリを見ると取得できている緯度経度は double 型なので、適宜 String に加工して使えそうです。

ソースコードは以下にあります。自分の勉強も兼ねて、これから実装するコード反映させるアプリケーションを作りました。
今後はこちらに更新されていく予定です。

補足

位置情報を取得できるライブラリはこの他に locationというのもあります。
ここでの導入の方法を見ると info.plist に Permissionを記載する記述があるので、geolocator同様に位置情報を取得するためには必須の記述のようです。
ネイティブエンジニアの方だったら常識なのかも知れないのですが、自分は初めて知りました。

まだこのライブラリを使いこなしている訳ではないので、位置情報に関してはもっと掘り下げて行きたいと思います。
あと、位置情報の精度に関しても選択ができるので、試してみるのも面白いかと思います。

精度

Android iOS
lowest 500m 3000m
low 500m 1000m
medium 100 - 500m 100m
high 0 - 100m 10m
best 0 - 100m ~0m
bestForNavigation 0 - 100m Optimized for navigation
38
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
30