【Flutter】GoogleMapの表示からgeolocatorで現在地を取得まで
概要
- GoogleMapの表示
- 現在地の取得及び表示
GoogleMapの表示
Google Cloud Platformでプロジェクトを作成する
GoogleCloudPlatformでプロジェクトを作成します。今回はプロジェクト名をgoogle map sampleにしてるよん
Maps SDK for iOS/Android API を有効にする
-
APIとサービスのライブラリをクリック
-
mapと検索すると
Maps SDK for iOS
とMaps SDK for Android
を発見じゃ
-
Maps SDK for iOS/Android
を有効にするゾ!
-
有効なAPIの欄にそれぞれ表示されていたらOK!
APIキーを発行する
-
APIとサービス>認証情報で「認証情報を作成」からAPIキーを発行する
-
発行したAPIキーをこの後に使用していくよ〜ん
パッケージをインストール
google_maps_flutter
をpubspec.yaml
に記述しpub get!
dependencies:
google_maps_flutter: ^2.1.3
Androidの設定
1. android/app/build.gradle
内の minSdkVersion
を20以上に設定する
android {
defaultConfig {
minSdkVersion 20
}
}
2. 先ほど取得したAPIキーをandroid/app/src/main/AndroidManifest.xml
に設定する
<manifest ...
<application ...
+ <meta-data android:name="com.google.android.geo.API_KEY"
+ android:value="YOUR KEY HERE"/>
YOUR KEY HERE
の部分に先ほど取得したAPIキーを設定する
Androidのエミュレータの注意点
↑Androidのエミュレータで表示されずに沼りました。
iOSの設定
- APIキーを
ios/Runner/AppDelegate.swift
に設定する
import UIKit
import Flutter
+ import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
+ GMSServices.provideAPIKey("YOUR KEY HERE")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
YOUR KEY HERE
にAPIキーを設定する
サンプルコードで動かしてみる
GoogleMapを表示するだけの最小構成
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Google Maps Demo',
home: MapSample(),
);
}
}
class MapSample extends StatefulWidget {
const MapSample({Key? key}) : super(key: key);
State<MapSample> createState() => MapSampleState();
}
class MapSampleState extends State<MapSample> {
late GoogleMapController _controller;
//初期位置
final CameraPosition _kGooglePlex = const CameraPosition(
target: LatLng(43.0686606, 141.3485613),
zoom: 14,
);
Widget build(BuildContext context) {
return GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
onMapCreated: (GoogleMapController controller) {
_controller = controller;
},
);
}
}
iOS | Android |
---|---|
iOS、Android両方表示できていればOK! ちなみに座標は札幌です!いいとこだよ
現在地の表示
location vs geolocator
現在地取得のパッケージとしてlocationとgeolocatorの2つが挙げられます。この2つを比較してみます!
location | geolocator | |
---|---|---|
Star数(2022/3/27時点) | 868 | 955 |
どちらでもできること
- デバイスの現在位置を取得
- 継続的な位置情報の更新
- 位置情報が有効になっているかどうかの確認
- 位置情報の許可のリクエスト
locationでできること
- backgroundで位置情報を受け取ることができる(geolocatorも8.2.0からできるようになったかも)
geolocatorでできること
- 最後に確認した位置を取得
- 2つの座標間の距離計算
- 2つの座標間の方位を計算
- 8.2.0からbackgroundで位置情報を受け取れるっぽい
次回以降の記事で2つの座標間の距離計算を使いたいのでgeolocatorを使っていくよん
geolocatorで現在位置の取得を実装
dependencies:
geolocator: ^8.2.0
pub get!!
iOSの設定
iOS/Runner/Info.plist
に以下を追加
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
Androidの設定
ACCESS_COARSE_LOCATION
かACCESS_FINE_LOCATION
のいずれかをandroid/app/src/main/AndroidManifest.xml
に追加する。
両方設定した場合はACCESS_FINE_LOCATION
が使用されるようです。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
FlutterのGeoLocationで位置情報を取ってみるの記事によると
位置情報に関する権限には、ACCESS_FILE_LOCATIONとACCESS_COARSE_LOCATIONがありますが、前者が詳細な位置。後者が大まかな位置情報となり、このパッケージでは、後者だと動かない場合があるようなので、詳細な位置情報を取得できる権限を要求しています。
とあるのでACCESS_FINE_LOCATION
を使用するのが無難かもしれないですね。
エミュレータの位置情報を設定
iOS
iOSはFeatures/Location/Custom Location
で現在位置を設定できます!!
Android
エミュレータの右下の・・・をタップ→Locationから位置情報を設定
実装
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Google Maps Demo',
home: MapSample(),
);
}
}
class MapSample extends StatefulWidget {
const MapSample({Key? key}) : super(key: key);
State<MapSample> createState() => MapSampleState();
}
class MapSampleState extends State<MapSample> {
Position? currentPosition;
late GoogleMapController _controller;
late StreamSubscription<Position> positionStream;
//初期位置
final CameraPosition _kGooglePlex = const CameraPosition(
target: LatLng(43.0686606, 141.3485613),
zoom: 14,
);
final LocationSettings locationSettings = const LocationSettings(
accuracy: LocationAccuracy.high, //正確性:highはAndroid(0-100m),iOS(10m)
distanceFilter: 100,
);
void initState() {
super.initState();
//位置情報が許可されていない時に許可をリクエストする
Future(() async {
LocationPermission permission = await Geolocator.checkPermission();
if(permission == LocationPermission.denied){
await Geolocator.requestPermission();
}
});
//現在位置を更新し続ける
positionStream =
Geolocator.getPositionStream(locationSettings: locationSettings)
.listen((Position? position) {
currentPosition = position;
print(position == null
? 'Unknown'
: '${position.latitude.toString()}, ${position.longitude.toString()}');
});
}
Widget build(BuildContext context) {
return GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
myLocationEnabled: true,//現在位置をマップ上に表示
onMapCreated: (GoogleMapController controller) {
_controller = controller;
},
);
}
}
iOS | Android |
---|---|
現在位置が表示されていれば成功!!
まとめ
本記事ではGoogleMapの表示からgeolocatorによる現在位置の取得まで行いました!
次の記事ではGoogleMap+カードのUI作成,geoflutterfireについての紹介を行います!
Discussion