Flutter SDK:桥接 Dart 和 Native
Tracelet 是独一无二的,因为它将几乎所有的逻辑推送到本机 iOS 和 Android SDK。为什么?因为 Dart 隔离很重,每次用户迈出一步时都会在后台唤醒 Flutter 引擎,这会破坏电池寿命。
本页介绍了 Flutter 层在现实场景中如何与原生引擎交互。
场景 1:UI 订阅
探索的概念: 事件流、无头执行
问题
您正在构建一个健身应用程序。当用户看着屏幕时,您希望有一个小蓝点在 Google 地图上实时移动。当用户锁定屏幕时,您仍然希望将运行记录到数据库中,但不需要更新没有人在看的 UI。
Tracelet 如何解决这个问题
Tracelet 将 本机跟踪引擎 与 Dart UI Streams 分开。
当您调用 Tracelet.start() 时,本机 iOS/Android 引擎就会启动。它完全在 Swift/Kotlin 中处理运动检测、GPS 过滤、SQLite 保存和 HTTP 同步。
在 Flutter UI 中,您只需订阅流即可:
import 'package:tracelet/tracelet.dart' as tl;
void initializeTracking() async {
// 1. Listen to events in the UI
tl.Tracelet.onLocation((tl.Location location) {
print('Update UI map marker: ${location.coords.latitude}, ${location.coords.longitude}');
});
tl.Tracelet.onMotionChange((tl.Location location) {
print('User started/stopped moving: ${location.isMoving}');
});
// 2. Start the native engine
await tl.Tracelet.ready(tl.Config.balanced());
await tl.Tracelet.start();
}魔法: 如果用户强制终止您的应用程序,onLocation Dart 流就会终止。 但本机跟踪引擎继续运行。 它继续将位置保存到 SQLite。当用户稍后重新打开应用程序时,您可以使用数据库适配器查询 SQLite 数据库来呈现他们的路线。
场景 2:入职流程
探索的概念: 权限处理、拒绝
问题
您正在为老年患者构建一款应用程序来跟踪行走情况。您需要“始终”后台位置权限。如果你只是向他们抛出系统权限对话框,他们会感到困惑,点击“拒绝”,然后该应用程序就变得毫无用处。
Tracelet 如何解决这个问题
Tracelet 从不自动请求权限。它将 UI 流程完全取决于您的 Flutter 代码,允许您在触发可怕的操作系统提示之前显示教育性自定义对话框。
import 'package:tracelet/tracelet.dart' as tl;
// 1. Check current status
final status = await tl.Tracelet.requestLocationAuthorization();
// 2. The user permanently denied permission in the past
if (status == tl.AuthorizationStatus.deniedForever) {
// Show a beautifully designed Flutter dialog explaining WHY you need it.
// Add a button that calls:
await tl.Tracelet.openAppSettings();
return;
}
// 3. We haven't asked yet, or they selected "Ask Next Time"
if (status == tl.AuthorizationStatus.notDetermined || status == tl.AuthorizationStatus.denied) {
// Ask for foreground permission first
final result = await tl.Tracelet.requestLocationAuthorization();
if (result == tl.AuthorizationStatus.whenInUse) { // They granted "When In Use"
// Show a second Flutter dialog explaining why "Always" is needed.
// Then upgrade the permission:
await tl.Tracelet.requestLocationAuthorization();
}
} Location Status
Tracelet.requestLocationAuthorization() 返回 AuthorizationStatus 枚举:
notDetermined:你还没问呢。denied:用户被拒绝(可以在 Android 上再次询问)。whenInUse:仅授予前台。always:已授予后台访问权限。deniedForever:用户选中“不再询问”或 iOS 永久拒绝。您必须将它们发送到设置。