よくある質問
一般的な権限とクラッシュ
権限を追加しないとどうなるでしょうか?クラッシュしてしまうのでしょうか?
いいえ、Tracelet はクラッシュしません。 Tracelet は復元力が高くなるように設計されています。必須の位置情報アクセス許可を宣言または要求せずに Tracelet.start() を呼び出そうとすると、Tracelet は SecurityException を適切にキャッチし、詳細なエラーをコンソールに記録し、失敗イベントをリスナーに出力します。アプリ自体は引き続き通常どおり実行されます。ただし、許可が与えられるまで位置は記録されません。
モーション (身体活動) 許可を有効にしないとどうなりますか?
いいえ、クラッシュしません。 ACTIVITY_RECOGNITION (Android) または Motion & Fitness (iOS) 権限が付与されていない場合、Tracelet は自動的に標準の距離ベースの追跡に戻ります。
ただし、バッテリーの消耗は大幅に増加します。動きを検出しないと、Tracelet はデバイスが静止しているときに GPS ハードウェアをスリープ状態にすることができません。最適なバッテリー寿命を確保するために、運用アプリに対してこの権限をリクエストすることを強くお勧めします。
iOSのビルドとセットアップ
iOS ビルドが「未定義シンボル」Rust/UniFFI エラーで失敗する (_ffi_tracelet_core_rustbuffer_free、_uniffi_tracelet_core_checksum_method_*)
Flutter の Swift パッケージ マネージャーの統合を有効にします。 Tracelet の Rust コア (tracelet_ios で使用される UniFFI シンボルを公開する TraceletCore.xcframework) は、Swift パッケージ マネージャーを通じてリンクされます。従来の CocoaPods 専用パスでは、フレームワークが tracelet_ios ターゲットにリンクされていないため、Xcode のリンカーは _ffi_tracelet_core_rustbuffer_free や _uniffi_tracelet_core_checksum_method_* などの未定義のシンボルを報告します。
次のように修正してください。
flutter config --enable-swift-package-manager
flutter clean
flutter pub get
flutter run # or: flutter build ios注:
.xcworkspaceを開いて Xcode から直接ビルドするのではなく、Flutter CLI または IDE (VS Code) からビルド/実行します。これにより SPM 対応ビルドが実行されます。- これは 1 回限りのグローバル Flutter 設定です。プロジェクトごとに変更する必要はありません。
flutter clean+ 新しいpod installだけではこの問題は解決されません**。不足している部分は、古い Pod ではなく、Rust フレームワークにリンクする SPM です。
バッテリーとモーションセンサー
モーションセンサーを使用すると、歩くとバッテリーの消費量が多くなりますか?
いいえ、実際にはバッテリーを節約します。 ハードウェア モーション センサー (加速度センサー/歩数検出器) の 1 時間当たりのバッテリー消費量は 0.1% よりも少なくなります。 Tracelet は、この超低電力センサーを使用して、電話機が机の上に置かれているときは常に、非常に電力を消費する GPS チップ (1 時間あたり 4-8% を消費します) を完全にオフにします。
歩き始めると、モーション センサーがすぐに GPS を起動して旅行を記録します。全体的な結果として、従来の追跡と比較してバッテリー寿命が大幅に向上します。
携帯電話が動いていないときに継続的に更新を取得できないのはなぜですか?
これは意図的なものであり、Tracelet が提供する最大のバッテリー節約です。 モーション検出によってデバイスが静止していると判断されると、Tracelet は継続的な GPS の電源を切り、低電力モード (定期的なワンショット修正またはジオフェンス監視) に切り替えます。実際の動きが再開されるとすぐに、連続追跡が自動的に起動します。
静止中に定期的に「ここにいます」位置が必要な場合は、heartbeatInterval (秒) を設定します。駐車中の小さな GPS ドリフトは走行距離計を膨張させません - odometerAccuracyThreshold (デフォルトの 50 m) よりも悪い修正は距離から除外されます。
バッテリーの使用量をさらに減らすにはどうすればよいですか?
Tracelet は静止しているときにすでに GPS をスリープ状態にしていますが、いくつかのレバーがあります。
- バッテリー予算 —
GeoConfigでbatteryBudgetPerHourを設定します (例:3.0を 3%/時間に設定)。その後、Tracelet は実行時にdistanceFilterとdesiredAccuracyを自動調整して、その目標を下回るようにします。 - ウェイクロック リリース — ユーザーが静止しているときに CPU を完全にスリープさせるには、
AndroidConfigにreleaseWakelockWhenStationary: trueを設定します (MotionDetectionMode.smartが必要)。 - 距離フィルター -
distanceFilter(メートル) が大きいほど、移動中に記録される修正の数が少なくなります。 - 精度が低い -
medium/lowのdesiredAccuracyは、high/bestより消費電力が低くなります。 - 定期モード — 「おおよそどこにあるのか」というユースケースの場合、定期的なワンショット修正 (
startPeriodic) は継続的な追跡よりも大幅に安価です。 - モーション許可を付与したままにします —
ACTIVITY_RECOGNITIONがないと、Tracelet は GPS を積極的にスリープさせることができません。
motionDetectionMode オプションの違いは何ですか?
motionDetectionMode は、Tracelet が動きを検出して GPS を開始/停止する方法を決定します。
accelerometer— ハードウェア モーション センサー (および許可されている場合はアクティビティ認識) を使用します。最低電力で、屋内で GPS 修正なしで動作します。speed— GPS 速度のみを使用します。シンプルで予測可能ですが、停止したことを認識するには GPS の修正が必要なため、反応が遅くなり、より多くの電力を消費します。smart— 両方を組み合わせます。加速度計 * または * GPS 速度の どちらか が移動していることを示している場合は継続的な追跡を続け、 両方 が停止したことに同意した場合にのみ静止します。誤った遷移に対して最も堅牢です。ほとんどのアプリで推奨されます。
位置情報サービスと追跡状態
追跡がアクティブなときにユーザーが位置情報サービスをオフにするとどうなりますか?
簡単な答え: Tracelet は追跡を停止、クラッシュ、破壊することはありません。追跡セッションの準備を維持し、アプリが反応できるように providerchange イベントを発行し、位置情報がオフになっている間は新しい位置情報を記録しません (以下の 2 つのプラットフォーム固有の例外を除きます)。また、ユーザーが位置情報を再度有効にすると、あらゆる状態 (フォアグラウンド、バックグラウンド、終了) で位置情報の配信を 自動的に再開します。 start() を再度呼び出す必要はありません。
ここでの「位置情報サービスのオフ」とは、OS レベルの位置情報の切り替えを意味します (Android: 設定 → 位置情報; iOS: 設定 → プライバシー → 位置情報サービス)。アプリの 権限 の取り消しは関連していますが、別のケースです。この回答の最後にある注を参照してください。
検出方法
final sub = tl.Tracelet.onProviderChange((tl.ProviderChangeEvent e) {
if (!e.enabled) {
// Location services were turned OFF — prompt the user / show a banner.
} else {
// Back ON — Tracelet has already resumed; no action required.
}
});ProviderChangeEvent には、enabled、status (認可)、gps、network、accuracyAuthorization、gpsFallback、および mockLocationsDetected が含まれます。同じイベントは、バックグラウンド/強制終了状態 (登録されている場合) で ヘッドレス コールバックに配信され、disableProviderChangeRecord: true を設定しない限り、providerchange レコードとして保持されます。
状態およびプラットフォームごとの動作
| 状態 | アンドロイド | iOS |
|---|---|---|
| 前景 | providerchange (enabled: false) が起動します。フォアグラウンド サービスは存続します。再度有効にするまで新しい修正はありません。 | providerchange が起動します。 didFailWithError は正常に処理されます (ワンショットは最後に知られている場所にフォールバックします)。新しい修正はありません。 |
| 背景 | フォアグラウンド サービス (およびその通知) は実行され続けます。融合された更新は単に停止します。 providerchange はまだディスパッチされています。再度有効にすると再開します。 | CLLocationManager サブスクリプションは登録されたままになります。 iOS は、位置が戻ってから再開するまで何も配信しません (リージョン/SLC 経由でアプリを再起動できます)。 |
| 終了 (殺害) | バックグラウンド/ブート セッションがアクティブな場合 (stopOnTerminate: false / startOnBoot)、サービスは上記の バックグラウンド として動作します。プロセスが生きていない場合は、次に OS がプロセスを開始するまで何も実行されません。 | iOS は、重要な位置/地域の監視を介してアプリを再起動します。位置/地域のイベントが発生した場合のみですが、位置情報がオフの場合は再起動できません。再度有効にすると、次の予選イベントが再起動して再開されます。 |
いずれの場合もセッション状態は保持されるため、位置情報を再度有効にすると、再初期化することなく自動的に追跡が再開されます。
Tracelet が「しない」こと
- セッションを自動停止したり、設定/状態をクリアしたりすることはありません。
- スローやクラッシュはしません。プラットフォームの「位置がオフ/拒否されました」エラーが捕捉されます。
- 位置情報を捏造するわけではありません** (下記の Android 推測航法を除く)。DB には位置情報がオフだった期間のギャップがあるだけです。
知っておくべきプラットフォームの詳細
Android — ユーザーが GPS を無効にしても、Wi-Fi/セル測位がオンのままの場合、Tracelet は自動的に電力バランス測位にフォールバックし、gpsFallback: true とともに providerchange を発行し、GPS が復帰すると完全な精度を回復します。これらのおおよその修正は**記録され、同期されます(locationSourceと実際のaccuracyでタグ付けされます)。 enableDeadReckoning: true の場合、設定された遅延時間にわたって GPS が失われた後、実際の修正が返されるまで、Tracelet はモーション センサーから位置を推定します。永続的な通知は全体を通して表示されたままになります。
iOS — requestLocation() が失敗すると、ハングするのではなく、最後の既知の場所でワンショット リクエストが解決されます。 iOS は、位置情報がオフになっている間はバックグラウンド イベントや再起動イベントを配信しません。再びオンにすると、配信と強制終了状態の再起動が再開されます。
アプリでやるべきこと
onProviderChangeを購読し、enabled == falseのときにバナー/ダイアログを表示します。- 必要に応じて、
Tracelet.openLocationSettings()を介してユーザーを設定に案内します。 - 再有効化時に
start()を再度呼び出さないでください**。Tracelet は自動的に再開します。start()の呼び出しは無害ですが、不要です。
アプリの「許可」を取り消すか、トグルをオフにするか
トグルをオフにするとすべてのアプリに影響しますが、上記のように完全に回復できます。 アプリの位置情報権限の取り消し (または「常に」→「使用中」へのダウングレード) は、status / accuracyAuthorization フィールドを介して同じ providerchange イベントによって報告されます。 Android 12 以降では、バックグラウンド位置の権限が失われると、ブート/バックグラウンドでの再起動が意図的にスキップされます (そうでなければ、サイレントに失敗します)。権限を再付与し、再初期化して再開します。
位置情報はどの程度正確ですか?また、GPS と Wi-Fi/携帯電話の位置情報をどのように区別すればよいですか?
すべての Location には、メートル単位の実際の coords.accuracy と locationSource タグが含まれます: "gps" (≤50 m)、"wifi" (≤200 m)、"cell" (さらに悪い)、または "network" (GPS フォールバック中)。 Tracelet は、低精度の修正を黙って削除しません**。追跡が継続するように修正を記録します。ただし、低精度の修正をオドメーターから除外し (odometerAccuracyThreshold、デフォルトの 50 m)、不可能な速度のジャンプを拒否します (maxImpliedSpeed)。
GPS 品質のデータのみが必要な場合は、locationSource == "gps" または accuracy <= 50 でフィルターをかけます。ユーザーが おおよそ/大まかな 位置情報のみを許可した場合 (または iOS の「正確: オフ」)、すべての修正は OS ポリシーによって近似値になります。accuracyAuthorization / reducedAccuracy を確認してください。
一部の電話機では getCurrentPosition() が LOCATION_FAILURE で失敗するのに、他の電話機では機能するのはなぜですか?
PlatformException(LOCATION_FAILURE, "Failed to obtain location") は、ワンショット リクエストが timeout 内で新しい修正を取得できず、フォールバック先のキャッシュされた場所がなかったことを意味します。これはコードのバグではありません。デバイスの GPS/融合スタックが時間内に修正を提供できなかったことです。高精度のワンショットでは 新鮮な 修正が必要ですが、それが (たとえば) 30 秒以内に成功するかどうかはデバイスと環境に大きく依存します。
- 「Google 位置情報の精度」がオフになっています — 設定 → 位置情報 → 位置情報サービス → Google 位置情報の精度 (Wi-Fi/Bluetooth スキャン)。オンにすると、融合プロバイダーはほぼ即座に屋内の Wi-Fi/セル修正を返します。オフの場合、電話機は生の GPS 修正を待つ必要がありますが、屋内に届くことはありません。 これが、「相手の携帯電話ではなく、私の携帯電話で動作する」の最大の原因です。
- 屋内/地下/空の眺めなし — コールド GPS 修正には空の可視性が必要であり、主力製品ではアシスト付き GPS 修正を数秒で取得できる一方で、低予算のチップセットではコールド ファースト フィックス (TTFF) に 30 秒を超える場合があります。
- GPS プロバイダーが OS レベルで無効になっている (ネットワークのみの位置情報) - 純粋な高精度リクエストにはロックするものがありません。
- Google Play サービスが見つからない/古い (一部の Huawei/AOSP ビルド) — 融合されたクライアントは実行できません。
- サンプル数 -
samples: 3を使用すると、Tracelet は 3 つの修正を収集する必要があります。限界信号では、1 つを取得しても、残りの前にタイムアウトになる可能性があります。samples: 1は屋内ではより寛容です。
信頼性を高める方法 — 最後に知られている場所にフォールバックします:
Future<tl.Location?> bestPosition() async {
try {
return await tl.Tracelet.getCurrentPosition(
desiredAccuracy: tl.DesiredAccuracy.high,
timeout: 60, // cold GPS fixes on budget phones can exceed 30 s
samples: 1, // more forgiving indoors than 3
maximumAge: 30000, // accept a <30 s-old cached fix instantly
);
} on PlatformException catch (e) {
if (e.code == 'LOCATION_FAILURE') {
// Weak/indoor signal — fall back to the cached fix before giving up.
return await tl.Tracelet.getLastKnownLocation();
}
rethrow;
}
}maximumAgeは、GPS を起動せずに、キャッシュされた最新の修正を即座に返します。30 秒前の位置が問題ない出席/チェックインに最適です。getLastKnownLocation()はプロバイダーをアクティブにすることはなく、融合されたキャッシュに保持されているものを返すため、実際に利用可能なものが何もない場合にのみ「弱い信号」メッセージが表示されます。- 起動後の最初の修正では
timeoutを十分な長さ (45 ~ 60 秒) に保ち、屋内での修正が失敗し続ける場合は、Google 位置精度を有効にするようユーザーに求めます (getProviderState()/getHealth()を介してプロバイダーの状態を検出します)。
背景と終了
Tracelet はアプリを閉じたりスワイプした後も追跡を続けますか?
Android — はい、stopOnTerminate: false を使用します。 ユーザーがアプリをスワイプして最近の履歴から削除すると、Tracelet は Flutter エンジンを必要としないネイティブ バックグラウンド サービスに追跡を引き渡すため、位置情報のキャプチャと同期は続行されます。永続的なフォアグラウンド サービス通知により、サービスが存続し続けます。 stopOnTerminate: true を使用すると、予想どおりスワイプで追跡が停止します。
iOS — アプリがどのように閉じられたかによって異なります。 iOS がメモリ/システム上の理由でアプリを終了した場合、次の重要な場所の変更時にバックグラウンドでアプリを再起動し、再開します。 ユーザーがアプリを強制終了すると (アプリスイッチャーで上にスワイプする)、iOS はアプリが再び開かれるまで、すべての位置情報サービスを意図的に一時停止します。Apple は、SDK でこれをオーバーライドすることを許可しません。
オフラインと同期
デバイスにインターネットがない場合、私の位置情報はどうなりますか?
何も失われません。 すべての修正は、ネットワークに関係なく、キャプチャされた瞬間にオンデバイス データベース (encryptDatabase: true の場合は暗号化されます) に書き込まれます。自動同期は、接続が回復したときにそれらをアップロードし、指数バックオフ (maxRetries、retryBackoffBase、retryBackoffCap) で再試行します。バッチは サーバーが受信を確認した後にのみデータベースから削除されるため、失敗または中断されたアップロードは単に再試行されるだけで、ドロップされることはありません。
保存制限内での場所のバッファー (maxDaysToPersist、maxRecordsToPersist)。これらを超えると、最も古いものは削除されます。 disableAutoSyncOnCellular: true を使用して、携帯電話からのアップロードを保留することもできます。
インターネットが復旧すると、tracelet_sync は自動的にバックエンドにプッシュされますか?
はい、完全にバックグラウンドで自動的に実行されます。 tracelet_sync (または tracelet_supabase / tracelet_firebase などのそのラッパー) を使用する場合は、ネットワーク再試行ロジックを自分で作成する必要はありません。
ネットワーク接続が復元されたことを OS が検出すると、ネイティブ同期エンジンがバックグラウンドですぐに起動し、キャッシュされた場所を時系列のバッチでバックエンドにアップロードし始めます。ローカル データベースがサーバーに完全に追いつくまでアップロードを続けるため、オフライン期間が長く続いた後でもデータ損失がゼロになります。
再起動とデバイスのロック解除
再起動後、デバイスのロックを解除する前に、Tracelet は追跡を開始しますか?
いいえ — 再起動後、Tracelet を再開する前にデバイスのロックを少なくとも 1 回解除する必要があります。 これは Android プラットフォームのルール (ダイレクト ブート / ファイルベースの暗号化) であり、Tracelet の制限ではなく、すべてのロケーション SDK に適用されます。
コールド ブート後、デバイスは ダイレクト ブート モードになり、ほとんどのアプリ データは暗号化されたままになります。 Android は、ユーザーが初めてデバイスのロックを解除した後 (PIN / パターン / パスワード / 生体認証)、Tracelet のブート レシーバーがリッスンする BOOT_COMPLETED ブロードキャストのみを配信します。それまでは、Tracelet の構成、状態、および場所のデータベースを保持する認証情報で暗号化されたストレージにはアクセスできません。つまり、読み書きできるものが何もありません。
したがって、再起動後のシーケンスは次のようになります。
- デバイスのブート → トレースレットはアイドル状態です。
- ユーザーが一度ロックを解除する →
BOOT_COMPLETEDが起動する → Tracelet が追跡と同期を再開します。
最初のロック解除のみが重要です。その後、画面を再度ロックすることができ (携帯電話をポケットに入れ、画面をオフにします)、追跡/同期は通常どおり続行されます。
ブート再開の要件: startOnBoot: true、stopOnTerminate: false、およびバックグラウンドロケーション (「常に」) 権限が付与されています。 Android 14+ では、OS は起動時から location フォアグラウンド サービスの開始をさらに禁止するため、Tracelet は次にアプリが開かれるまで WorkManager/アラーム追跡 (永続的な通知なし) に戻ります。
iOS は再起動時にまったく自動起動できません。アプリは起動時に実行できず、ユーザーがアプリを開くか、重大な場所の変更によってアプリが再起動されるまで起動されないままになります。これ自体は、再起動後の最初のロック解除後にのみ行われます。
最初のロック解除「前」を追跡できますか?
デフォルトではありません。ロックを解除する前に位置情報を取得するには、Android ダイレクト ブートが必要です。これは、Tracelet が必要とするデータを デバイス暗号化 ストレージに移動することを意味します。これは、ユーザーが認証する前に読み取り可能であり、Tracelet が通常使用する認証情報で暗号化された (およびオプションで encryptDatabase で保護された) ストレージよりも保存時の保証が弱くなります。データを完全に保護するために、Tracelet はすぐにダイレクト ブートを有効にしません**。ロック解除前の追跡がユースケースにとって厳しい要件である場合は、高度なアプリレベルのオプトインとして有効にすることができます。それに依存する前に問い合わせてください。
ジオフェンシング
モック/シミュレートされた場所でテストすると、ジオフェンス トランジションが起動しません (1.x では機能しました)
モック位置は引き続き機能しますが、高精度ジオフェンス モードでは、ジオフェンスが評価される前にモックされた修正がフィルターで除外されます。 geofenceModeHighAccuracy: true を使用すると、遷移は連続 GPS ストリームからアプリ内で計算され、エバリュエーターは位置フィルターを通過した修正に対してのみ実行されます。ルート シミュレーション ツールは通常、ポイント間を「テレポート」しますが、これらのジャンプは以下によって拒否されます。
maxImpliedSpeed— 遠く離れた 2 つのサンプル間の信じられない速度は外れ値として扱われ、削除されます。useKalmanFilter: true— よりスムーズな戦闘、突然の非物理的な模擬ジャンプ。trackingAccuracyThreshold- 一部の模擬プロバイダーは、accuracy = 0、またはしきい値を満たさない非現実的な値を報告します。
現在の位置に配置されたジオフェンスは、geofenceInitialTriggerEntry: true が登録時に ENTER を発行する (移動は必要ない) ため、依然として起動します。そのためフィルターを通過することはありません。
高精度モードでの模擬テストの場合は、フィルターを緩和します。
filter: tl.LocationFilter(
rejectMockLocations: false,
useKalmanFilter: false, // disable smoothing
maxImpliedSpeed: 0, // 0 disables the implied-speed reject
trackingAccuracyThreshold: 0, // accept regardless of reported accuracy
),
geo: tl.GeoConfig(distanceFilter: 0, disableElasticity: true),また、開発者向けオプション → 模擬位置情報アプリの選択 で模擬アプリを選択し、現実的な小さなステップでシミュレートされたルートを進めます。
最も簡単な方法は、OS ジオフェンス サービスに委任する 標準 ジオフェンス モード (geofenceModeHighAccuracy: false) でテストすることです。 OS は、融合されたプロバイダーに対して評価し、SDK フィルターを使用せず、システムのモックロケーション アプリを尊重します。OS は実用的な最小値を強制し、それを下回る小さな/EXIT 遷移は信頼できないため、そこでは ≥ ~100 m の半径を使用します。
debug: true と logLevel: verbose を使用する場合は、Location filtered by Rust processor: <reason> のログを監視してください。これにより、各モック修正をドロップしたフィルターが正確にわかります。
データセキュリティとプライバシー
私の位置データは保存時に暗号化されますか?
オプションで、はい。 encryptDatabase: true を設定して、場所をバッファーするローカル SQLite データベースを暗号化します。 Android では、これは SQLCipher (AES-256) を使用し、アプリに SQLCipher 依存関係を追加する必要があります。これはオプションのままであるため、デフォルトのビルドは小さいままであり、これなしで encryptDatabase を呼び出すと明らかなエラーがスローされます。 iOS では、暗号化ストアはネイティブに処理されます。
機密性ではなく改ざん証拠を目的として、監査証跡 (audit.enabled) によって各レコード (SHA-256 など) がハッシュチェーン化されるため、履歴が事後に変更されていないことを証明できます。 プライバシー ゾーン を使用すると、機密エリア (ユーザーの自宅など) 内の修正を抑制または編集できます。
Tracelet は偽/偽の GPS 位置を検出しますか?
はい、LocationFilter の mockDetectionLevel 経由:
disabled(デフォルト) — すべての場所が無条件に受け入れられます。basic— プラットフォームの「is mock」フラグを信頼します。heuristic— プラットフォーム フラグ プラス ネイティブ ヒューリスティックと Dart 側のタイムスタンプ チェックにより、フラグを隠すスプーファーを検出します。
heuristic では、各 Location に本物か偽物と判断された理由の注釈が付けられるため、独自のロジックで模擬修正を受け入れたり、フラグを立てたり、拒否したりできます。
flutter_background_geolocation からの移行
flutter_background_geolocation から来ました — 切り替えはどれくらい難しいですか?
Tracelet の API は意図的に flutter_background_geolocation に近いため、ほとんどのアプリは最小限の変更でマッピングされます。ready/start/stop、位置/モーション/プロバイダー イベント、および HTTP 同期はすべて直接同等のものです。構成/イベント マッピング テーブルと注意すべきいくつかの動作の違いについては、完全な 移行ガイド を参照してください。