概要
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
お約束ですね
dependencies:
geolocator: ^5.1.3
2. ios/Runner/info.plist
にpermissionを記載する
iOS doesn't ask for Location permissionsで記載されているエラーが発生しているので、どうも 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. 実装してみる
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 |