Google Mapを使ったアプリ作成
現在、Flutterのアプリケーション作成をしています。
様々なアプリでGoogle Mapが利用されていますが、どのように実現するのか知りたかったのでやってみました。
私の端末はAndroidのため、Androidに限った話となり恐縮ですが、よろしくお願いします。
また今回の内容ですが、2本立で構成します。
本記事は1本目として、環境準備と機能構築の基礎的な内容を扱います。
アプリ上でGoogleMapを表示できる状態へ
まずはFlutterのアプリで表示できる状態まで持っていきます。
Google Cloudを利用しますが、アカウント作成とプロジェクト作成は、割愛します。
公式ドキュメントを参照ください。
APIの有効化
以下、APIが提供されているので、必要に応じてAPIを有効化します。
- Android
- iOS
- JavaScript(Web)
私はとりあえずAndroidから進めているので、以下を選択します。
有効化をクリックすると、請求先アカウントを聞かれます。
APIキー作成
Google CloudのコンソールからAPIキーを作成します。
続けて、APIキーに対して制限をかけます。キー名さえ知っていれば誰でも利用可能な状態を防ぎます。
APIの制限
今回はMap関係のAPI2つだけあればOKなので、以下のように設定します。
アプリケーションの制限
Androidを選択すると、
パッケージ名とフィンガープリントを聞かれます。
-
パッケージ名:
android/app/build.gradle
のapplicationId
の値 -
フィンガープリント:
ターミナルでgraldew
コマンドの実行結果に出力されたSHA-1の値です。
ただしこれは開発中に用います。
本番環境などで使用する場合は、keytool
コマンドなどを用いたキー作成作業が必要です。cd android ./gradlew signingReport
これでAPIキーの設定は完了です。
APIキー値の取得
「鍵を表示します」という部分をクリックすると、鍵の値をコピーできるようになるので、コピーしてください。
APIキーの読み込み設定
最後に、取得した値をアプリケーションで読み込めるようにコードを修正します。
android/app/src/main/AndroidManifest.xml
に以下内容を追加します。
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="sample"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:enableOnBackInvokedCallback="true"
>
<!-- ここから下が今回関係する部分 -->
+ <meta-data
+ android:name="com.google.android.geo.API_KEY"
+ android:value="${MAPS_API_KEY}" />
MAPS_API_KEY
にAPIキーの代入する形で設定します。(Gitでキー値が保存されない形)
変数:MAPS_API_KEY
の定義ですが、
androidフォルダ直下のsecrets.properties
に、以下のように記載します。
MAPS_API_KEY=XXXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXX
.gitignoreへの追加
.gitignore
に、secrets.properties
を追加する作業は忘れずに実施してください。
間違ってPushした場合は、APIキーの再作成するのが望ましいです。
AndroidManifest.xml
の記載ミスによるエラー
Unhandled Exception: PlatformException(error, API key not found. Check that is in the element of AndroidManifest.xml, null, java.lang.RuntimeException: API key not found. Check that is in the element of AndroidManifest.xml
AndroidManifest.xml
の記載を間違えてしまうと発生してしまうエラーのようです。
記載箇所にはご注意ください。いくつかIssueになっていたので、間違えやすい箇所なのかもしれません。
アプリケーションで使用するための準備はこれで完了です。
ここから具体的な実装をベースにした話をします。
機能構築:基礎編
1.初期表示位置を設定
まずはGoogleMapをアプリケーションで表示できるようにします。
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class SecondTabMapScreen extends StatefulWidget {
const SecondTabMapScreen({super.key});
@override
State<SecondTabMapScreen> createState() => MapSampleState();
}
class MapSampleState extends State<SecondTabMapScreen> {
final Completer<GoogleMapController> _controller = Completer<GoogleMapController>();
static const CameraPosition _kTokyo = CameraPosition(
target: LatLng(35.681236, 139.767125),
zoom: 14,
);
@override
Widget build(BuildContext context) {
return Scaffold( body:
GoogleMap(
initialCameraPosition: _kTokyo,
onMapCreated: (controller) {
_controller.complete(controller);
},
),
);
}
}
2.現在地を表示
次は自分の位置を表示します。
GoogleMap
ウィジェットのプロパティ:myLocationEnabled
を追加するだけです。
以降の実装について、基本的には関係する箇所を追加し、その部分を差分として表示する形をとります。
現在位置を表示するための実装例
@override
Widget build(BuildContext context) {
return Scaffold(
body: GoogleMap(
initialCameraPosition: _kTokyo,
+ myLocationEnabled: true,
onMapCreated: (controller) {
_controller.complete(controller);
},
),
);
}
3.Markerを設定
以下画像の赤いピンのことです。
緯度・経度を指定して表示できるようにします。
地図にMarkerを表示するために、Marker
ウィジェットを使います。
Id(識別するためのもの)と具体的な緯度・経度の情報が必要です。
変数:_markers
に各地点の情報を格納した上で、
GoogleMap
ウィジェットのプロパティ:markers
に_markers
を設定します。
Markerを表示するための実装例
class SecondTabMapScreen extends StatefulWidget {
const SecondTabMapScreen({super.key});
@override
State<SecondTabMapScreen> createState() => MapSampleState();
}
class MapSampleState extends State<SecondTabMapScreen> {
final Completer<GoogleMapController> _controller = Completer<GoogleMapController>();
+ final Set<Marker> _markers = {}; // Marker情報を格納する変数を追加
static const CameraPosition _kTokyo = CameraPosition(
target: LatLng(35.681236, 139.767125),
zoom: 14,
);
+ @override
+ void initState() {
+ super.initState();
+ _loadMapWithMarkers();
+ }
+
+ Future<void> _loadMapWithMarkers() {
+ _addMarkers();
+ }
// Markerを追加
+ void _addMarkers() {
+ _markers.clear();
+
+ for (int i = 0; i < positions.length; i++) {
+ _markers.add(
+ Marker(
+ markerId: MarkerId('marker_$i'),
+ position: positions[i],
+ ),
+ );
+ }
+ }
@override
Widget build(BuildContext context) {
return Scaffold( body:
GoogleMap(
initialCameraPosition: _kTokyo,
myLocationEnabled: true,
+ markers: _markers,
onMapCreated: (controller) {
_controller.complete(controller);
},
),
);
}
}
// 緯度経度の情報
+ final List<LatLng> positions = [
+ LatLng(35.682839, 139.759455), // 東京駅
+ LatLng(35.658034, 139.701636), // 渋谷駅
+ LatLng(35.689487, 139.700302), // 新宿駅
+ ];
4.デフォルト値の設定更新
GoogleMap
ウィジェットで特に設定をしなかった場合に、以下のように表示されます。
設定ONのときのスクリーンショット
実装順が前後した関係で、Markerタップ時の実装が既にされていますが、気にせず確認いただければと思います。3カ所あります。
要不要はアプリケーションによりきりですが、デフォルトで表示されていた内容を一通り消してみます。
デフォルトの表示を消すための実装例
@override
Widget build(BuildContext context) {
return Scaffold( body:
GoogleMap(
initialCameraPosition: _kTokyo,
myLocationEnabled: true,
markers: _markers,
+ myLocationButtonEnabled: false, // 1. 現在地へ移動するボタン非表示
+ zoomControlsEnabled: false, // 2. +/−ボタン非表示
+ mapToolbarEnabled: false, // 3. ツールバー非表示
onMapCreated: (controller) {
_controller.complete(controller);
},
),
);
}
}
実装後
まとめ
FlutterでGoogleMapを用いた機能作成に関して取り組んでみました。
実装はサクッとできる内容だったので、環境構築の方が気持ち大変だったかと思います。
Part2として応用的な内容についてまとめていますので、お待ちください!
ありがとうございました。
参考記事