LoginSignup
3
1

flutterでgeofenceを使ってみた

Last updated at Posted at 2023-12-07

18歳学生のHaruです!

この後の話題にも出ますが、最近Restinという休憩場所を手軽に見つけられるSNSのようなマップアプリをリリースしました!
ログイン無しでもご利用いただけるので、是非使ってもらえるととても嬉しいです!

スクリーンショット 2023-11-06 1.02.31.png

まずGeofenceとは

Geofence
仮想的な境界線で囲まれた任意のエリア
引用

Geofencing
対象がGeofenceに入ったとき、又は出たときに、アプリやソフトウェアで所定のアクションを実行すること
引用

概要

前々からこのアプリにGeofencingを使って、機能追加をしたいと思っていたので、flutter_background_geolocationパッケージを使ってみました。
私のアプリの場合、休憩場所(ピン)に向かう前に、すでに他の人に使用されているかを判断できる機能を作るために、Geofencingを利用して、休憩場所の使用中かのステータスを見れるようにしました。

この記事では導入、利用方法などを紹介します!

開発環境

  • flutter 3.16.0
  • google_maps_flutter 2.3.1
  • flutter_background_geolocation 4.13.4

flutter_background_geolocationパッケージのAndroid対応について
このパッケージを使用して、Androidのリリースビルドをしたい場合、ライセンスの購入が必要になります。
今回はiOSの導入のみご紹介させていただきます、ご了承ください。
(iOSはアプリをリリースしても関係ありません。)

今回google_maps_flutterの導入は紹介しません。

導入

① packageの追加

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
    flutter_background_geolocation: 4.13.5

② iOSの設定

Info.plist
<dict>
+    <key>NSMotionUsageDescription</key>
+    <string>Motion usage description</string>
+    <key>NSLocationWhenInUseUsageDescription</key>
+    <string>When in use description</string>
+    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+    <string>Always/When in use description</string>

+    <key>UIBackgroundModes</key>
+    <array>
+        <string>fetch</string>
+        <string>location</string>
+    </array>
</dict>
Androidの設定

こちらでも記述した通り、Androidの設定紹介はしません。ご了承ください🙇🏻‍♂️
Androidの設定公式Docはこちら

③ 初期化処理

クラスにパッケージをインポートし、

home_page.dart
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;

Location, Config, Stateなど他のパッケージでも使われていそうな、クラスとの混同を防ぐため、as bgとprefixをします。

初期化処理を記述して

home_page.dart
  Future<void> initialize() async {
    await bg.BackgroundGeolocation.ready(
      bg.Config(
        desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
        distanceFilter: 10.0,
        stopOnTerminate: false,
        startOnBoot: true,
        debug: true,
        logLevel: bg.Config.LOG_LEVEL_VERBOSE,
      ),
    ).then((value) async {
      await bg.BackgroundGeolocation.start().then((value) {
        print('BackgroundGeolocation started');
      });
    });
  }

実行します。

home_page.dart
@override
  void initState() {
    super.initState();
    initialize();
  }

これで導入完了🎉

Geofenceをマップに追加する

① まずは追加するリストの変数を用意し、マップに表示したいピンの数だけloop処理をする

final geofences = <bg.Geofence>[];
for (final marker in markers) {
    geofences.add(
        bg.Geofence(
          identifier: marker.markerId,
          radius: 60.0,
          latitude: marker.latitude,
          longitude: marker.longitude,
          notifyOnEntry: true,
          notifyOnExit: true,
        ),
    );
}
  Future<bool> addGeofences(List<bg.Geofence> geofences) async {
    try {
      await bg.BackgroundGeolocation.addGeofences(geofences);
      debugPrint('addGeofences success');
      return true;
    } on Exception catch (e) {
      debugPrint('addGeofences failed $e');
      return false;
    }
  }

② マップにGeofenceを追加しただけでは見えないので、可視化していきましょう

google_maps_flutterパッケージにCircleクラスという便利なものがあるので、使っていきましょう!

final circles = <Circle>[];
for (final marker in markers) {
    circles.add(
      Circle(
        circleId: CircleId(marker.markerId.value),
        center: marker.position,
        strokeColor: ColorName.amber.withOpacity(0.8),
        fillColor: ColorName.amber.withOpacity(0.2),
        strokeWidth: 2,
        radius: markerCircleRadius,
         ),
    );
}

③ 追加

GoogleMap(
...
circles: circles.toSet(),
...
)

ここまででマップ上にGeofenceを追加することができました!

Geofenceへの出入りのアクションを追加

① Geofenceでのアクションハンドリングをする関数を作成

Future<void> eventOnGeofence(bg.GeofenceEvent event) async {
  if (event.action == 'ENTER') {
    print('GeofenceEvent: [--ENTER--]$event');
    // Geofenceに入った際に実行したいことを記述
  } else if (event.action == 'EXIT') {
    print('GeofenceEvent: [--EXIT--]$event');
    // Geofenceから出た際に実行したいことを記述
  }
}

② 関数を実行する

home_page.dart
  Future<void> initialize() async {
    await bg.BackgroundGeolocation.ready(
      bg.Config(
        desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
        distanceFilter: 10.0,
        stopOnTerminate: false,
        startOnBoot: true,
        debug: true,
        logLevel: bg.Config.LOG_LEVEL_VERBOSE,
      ),
    ).then((value) async {
      await bg.BackgroundGeolocation.start().then((value) {
        print('BackgroundGeolocation started');
      });
    });

+    bg.BackgroundGeolocation.onGeofence((bg.GeofenceEvent event) async {
+      await eventOnGeofence(event);
+    });
  }

作成できた機能

Geofenceに入場時

Geofenceから退場時

無限に使い道やアイデアを考えられるGeofenceにとても興味をそそられますよね!!!!

退場時の処理がうまく走っていない部分は頑張って修正します😇

最後に

初めて、Qiitaに投稿をすると共に、初めてAdventCalendarに投稿しました!
周りの記事がつよつよすぎて、こんな記事あげていいのかと思いましたが、あまりflutterの記事でGeofenceについての話題を見ないので、個人的には満足したと思い込むとします!!

雑な記事でしたが、ご覧いただきありがとうございました!!!!!😭

Geofence機能を追加したアプリのリポジトリ

参考

著者

(ちなみに25卒です...)
https://www.wantedly.com/id/haru_kobayashi_dev

3
1
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
3
1