Skip to Content
中心となる概念ジオフェンシング

ジオフェンシング API

Tracelet は、堅牢なオフラインファーストのジオフェンシング エンジンを提供します。 20 ~ 100 のジオフェンスに制限され、OS がアプリを起動する必要がある標準の OS ジオフェンスとは異なり、Tracelet は Rust エンジン内で内部的にジオフェンスを評価します。これにより、追加のバッテリー消耗をゼロにしながら無制限のジオフェンスが可能になります。


1. 円形ジオフェンスと多角形ジオフェンス

Tracelet は、標準的な円形ジオフェンスと複雑なポリゴン ジオフェンスの両方をサポートします。

円形ジオフェンス

円形のジオフェンスは、中心座標と半径 (メートル単位) によって定義されます。

final circular = tl.Geofence( identifier: 'headquarters', latitude: 37.7749, longitude: -122.4194, radius: 200, // 200 meters notifyOnEntry: true, notifyOnExit: true, notifyOnDwell: true, // Triggers if they stay inside loiteringDelay: 300, // Trigger dwell after 5 minutes );

ポリゴンジオフェンス

ポリゴン ジオフェンスは、複雑な形状 (公園や建物など) の輪郭を描く座標の配列によって定義されます。

final polygon = tl.Geofence.polygon( identifier: 'golden_gate_park', vertices: [ tl.Coordinate(latitude: 37.773972, longitude: -122.431297), tl.Coordinate(latitude: 37.769996, longitude: -122.511055), tl.Coordinate(latitude: 37.764516, longitude: -122.508566), ], notifyOnEntry: true, notifyOnExit: true, );

2. ジオフェンスの追加と削除

Tracelet は、すべてのジオフェンスをローカル SQLite データベースに保存します。これは、アプリが再起動されても永続的であることを意味します。アプリを起動するたびにそれらを再追加する必要はありません。

ジオフェンスの追加

単一のジオフェンスまたはジオフェンスの配列を追加できます。

// Add a single geofence await tl.Tracelet.addGeofence(circular); // Add multiple geofences efficiently await tl.Tracelet.addGeofences([circular, polygon]);

ジオフェンスの削除

一意の識別子を使用してそれらを削除するか、データベース全体をクリアします。

// Remove a specific geofence await tl.Tracelet.removeGeofence('headquarters'); // Remove all geofences entirely await tl.Tracelet.removeGeofences();

3. アクティブなジオフェンスの一覧表示

いつでも SQLite データベースにクエリを実行して、現在監視されているジオフェンスを確認できます。

final geofences = await tl.Tracelet.getGeofences(); for (final fence in geofences) { print('Monitoring: \${fence.identifier}'); }

4. ジオフェンス イベントのリッスン

ユーザーがジオフェンスの境界を越えると、Tracelet は onGeofence イベントを起動します。評価は位置情報の更新中に Rust コアで行われるため、アプリが強制終了された場合でも、これらのイベントは発生します (ヘッドレス コールバックがトリガーされます)。

tl.Tracelet.onGeofence((evt) { if (evt.action == tl.GeofenceEventAction.ENTER) { print('User entered: \${evt.identifier}'); } else if (evt.action == tl.GeofenceEventAction.EXIT) { print('User exited: \${evt.identifier}'); } else if (evt.action == tl.GeofenceEventAction.DWELL) { print('User is dwelling inside: \${evt.identifier}'); } });

5. Android: フォアグラウンド サービスと Google Play ポリシー

Google Play のポリシー変更 — 2026 年 10 月 28 日発効。 ジオフェンシングは無効です フォアグラウンド サービスの場所の使用が許可されるようになりました。を使用するアプリ ジオフェンシングのためのフォアグラウンド サービス のみ を削除する必要があります。 FOREGROUND_SERVICE_LOCATION (および使用されていない場合は FOREGROUND_SERVICE) マージされたマニフェストからのアクセス許可。

Tracelet の 標準 ジオフェンス モードは、ネイティブ Android Geofence API を使用します (GeofencingClient)、ENTER/EXIT が起動され、アプリが再起動されます。 ヘッドレス タスク — アプリが一時停止または終了している間、なしで フォアグラウンドサービス。標準モードで startGeofences() を呼び出すと 開始されません フォアグラウンド サービス (3.5.x 時点) であるため、デフォルトで準拠しています。

積極的な OEM (Samsung/Xiaomi/Huawei/OnePlus/Oppo/Vivo): 3.6.1 時点、 明示的な geofenceModeHighAccuracy: false はすべてのデバイスで受け入れられます。前に 3.6.1 これらの OEM は、黙って高精度モードを強制しました。 フォアグラウンド サービスとその永続的な通知 - false を設定した場合でも、 これにより、上記の準拠した標準モード パスが破壊されました。これらのデバイスをターゲットにすると、 3.6.1 以降を使用してください。積極的な OEM では、SDK が信頼性に関する警告をログに記録するようになりました。 構成をオーバーライドする代わりに (ネイティブ ジオフェンスの配信が遅れる可能性があります)。

Tracelet をジオフェンシングのみに使用する場合

  1. フォアグラウンド サービスを有効にしないでください

    await tl.Tracelet.ready(const tl.Config( android: tl.AndroidConfig( foregroundService: tl.ForegroundServiceConfig(enabled: false), ), geofence: tl.GeofenceConfig(geofenceModeHighAccuracy: false), )); await tl.Tracelet.startGeofences();

2.Tracelet SDK は FOREGROUND_SERVICE / FOREGROUND_SERVICE_LOCATION を宣言します 継続的な追跡のユースケースについて。アプリが継続的に実行しない場合 追跡、manifest-merger を使用してマージされたマニフェストからそれらを削除します アプリの android/app/src/main/AndroidManifest.xml 内の remove ルール:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove" /> </manifest>

継続的追跡 * および * ジオフェンシングを使用する場合

追跡のユースケースでは FOREGROUND_SERVICE_LOCATION を保持しておくこともできます (例: ナビゲーション/フリート追跡)、ただしフォアグラウンド サービスは次の目的で使用してはなりません。 ジオフェンシング。 Tracelet はすでにこれを処理しています。FGS は継続的な追跡のために実行されます。 (start())、およびジオフェンス専用モード (標準では startGeofences()) への切り替え モード)FGS を破棄します。

高精度ジオフェンス モード (geofenceModeHighAccuracy: true) は、 継続的な GPS により、アプリ内で厳密な境界を検出します。これにより、 フォアグラウンドサービス。これは継続的な位置情報であり、ポリシーの「ジオフェンシング」ではありません 意味 – したがって、アプリに位置情報の使用が別途許可されている場合にのみ有効にします 場合。ほとんどのアプリでは、標準モードが準拠しており、バッテリー効率の高い選択となります。

6. GPS ドリフトと誤った EXIT イベント (高精度モード)

高精度モードでは、トランジションはすべての GPS 修正からアプリ内で評価されます。あ 小さなジオフェンスのすぐ内側に静止しているデバイスは、時折、 たとえ動かなかったとしても、半径のかなり外側に漂っている単一の修正。に 誤った EXIT が起動されるのを防ぐため、Tracelet の終了決定は次のとおりです。 精度を考慮: 円形ジオフェンスは、全体 GPS エラーが発生した場合にのみ終了します。 サークルがフェンスを越える:

EXIT fires when: distance - horizontalAccuracy > radius + buffer

修正では 160 m アウトと報告されましたが、±150 m の精度ではせいぜい「10 m アウト」に過ぎません 楽観的であるため、まだ内部にあるものとして扱われ、EXIT は発生しません。自信のある、 同じ距離での正確な修正は正常に行われます。 ENTER は意図的に残されています 精度に依存しないため、到着はすぐにトリガーされます。

トレードオフ

終了しきい値は修正の報告された精度とともに増加するため、本物 現在の GPS の不確実性により、出発が遅れています。 50mのジオフェンスの場合 (70 メートルの出口閾値):

|水平精度 | EXIT は ~ | で起動します。 | ------------------- | --------------- | | ±8 m (良好、屋外) | 78メートル | | ±20m (標準) | 90メートル | | ±50m(不良) | 120メートル | | ±150m (非常に悪い) | 220メートル |

信号が良好な屋外では、これは無視できます。慢性的に GPS が低下している場合 状況(屋内の奥深く、都市の峡谷)では、実際の出口が著しく遅れる可能性があります。

チューニング: geofenceExitAccuracyMax

ユースケースがより高速で積極的な EXIT を好む場合、または、 最悪の場合の遅延 — GeofenceConfig.geofenceExitAccuracyMax (メートル単位) を設定します。

行動
-1 (デフォルト)完全な精度のゲート。ドリフトによる誤終了に対して最も耐性があります。 genuine exits may lag by the current GPS uncertainty.
非トランスレートゲーティングが無効になりました。 EXIT は、報告されたポイントが radius + buffer をクリアするとすぐに起動します。これは最速の終了ですが、単一のドリフト スパイクによって誤った EXIT が生成される可能性があります。
非トランスレートクランプ。 N メートルまでのドリフトを吸収しますが、実際の EXIT を ~N メートル以上遅らせないでください。混合条件の小さなフェンスに適した中間点 (例: 20)。
await tl.Tracelet.ready(const tl.Config( geofence: tl.GeofenceConfig( geofenceModeHighAccuracy: true, // Absorb drift up to 20 m, but keep genuine exits reasonably prompt. geofenceExitAccuracyMax: 20, ), ));

このゲートは 高精度のアプリ内パスにのみ適用されます。標準では (OS 領域監視) モードでは、オペレーティング システムが EXIT を決定し、 geofenceExitAccuracyMax は効果がありません。

確認された終了: 単一の悪い修正によって EXIT がトリガーされることはありません

精度ゲーティングは、ドリフト修正がその不確実性について「正直」である場合にのみ役立ちます。 (報告された精度は大きい)。一部のデバイスはその逆を行い、 自信過剰の修正により、フェンスの数百メートル外に着地してしまいました。 厳密な精度を報告します。報告された精度が小さいため、ゲーティング それを見抜くことはできません — 200 m − 1.7 m = 198 m は依然としてしきい値をクリアしています。

Tracelet は、2 番目の補完的な防御でこれらをキャッチします。EXIT は次のとおりです。 2 回連続のフェンス外修正で確認済み。推論は 物理的 — ジオフェンスから離れることは 持続的な変化ですが、自信過剰な場合は グリッチは常に 1 つの修正で発生し、すぐに内部に戻ってきます。 1つ:

fix 1: 200 m out → held (pending confirmation), no EXIT fix 2: back inside → pending cleared, glitch absorbed

本物の出発は外に残っているため、2 番目の修正によりそれが確認され、正確に確認されます。 1 つの EXIT が起動します - 1 つの位置情報更新によってのみ遅延します (高精度では約 1 秒) モード)。ヒステリシスは終了決定の 空間的 半分であり、これは 時間的半分。二人は一緒に働きます。

これはデフォルトでオンになっており、構成は必要ありません。決断はRustに宿る コアなので、Android と iOS は同じように動作します。 (精度ゲートと同様に適用されます) 高精度のアプリ内パスのみ — 標準の OS 領域監視モードでは、 オペレーティング システムが EXIT 決定を所有します。)