Skip to Content
入门平台设置安卓软件开发工具包

Android SDK:驯服电池管理器

Android 因主动终止后台服务而臭名昭著。中国 OEM 厂商(如小米、华为)甚至拥有自定义电源管理器,完全突破了标准 Android 后台执行限制。

本页解释为什么Android 会杀死您的应用程序以及如何Tracelet 的特定 Android 配置在现实世界中解决它。


可选依赖:高精度GMS定位

Tracelet 的 Android SDK 可以使用 Google Play Services LocationFusedLocationProviderClient (更好的准确性和电池),硬件活动识别(步行/驾驶/静止), 和硬件地理围栏。为了保持 SDK 的轻量级并可在无 Google 的设备上使用,这 依赖关系未捆绑。仅当您想要高精度路径时才添加它:

// android/app/build.gradle.kts dependencies { implementation("com.google.android.gms:play-services-location:21.3.0") }

它是可选的,SDK 会正常降级。 没有 play-services-location、Tracelet 退回到标准 AOSP LocationManager(普通 GPS)。追踪仍然有效——你只需 失去融合提供商的准确性/电池优势、硬件活动识别和硬件 地理围栏。 推荐: 添加它,除非您专门针对无 Google / AOSP 设备 (例如没有 GMS 的华为,或去谷歌的 ROM)。

最低版本:21.2.0 Tracelet的Android代码调用基于接口 FusedLocationProviderClientActivityRecognitionClient API,仅成为 play-services-location 21.2.0 中的接口。较旧的版本(例如 19.0.0)提供了这些 作为具体的类,所以调用它们会抛出 运行时 java.lang.IncompatibleClassChangeError。 Tracelet 发布 Gradle 依赖约束,如果满足以下条件,则自动将 play-services-location 提升为 21.2.0+ 另一个依赖项会引入旧版本,但如果您自己固定版本,请将其保留在 21.2.0 或更新版本(我们推荐 21.3.0)。

play-services-location没有它(AOSP 后备)
融合定位(最佳精度+电池)原始 GPS/网络通过 LocationManager
硬件活动识别(onActivityChange仅加速度计运动检测
硬件地理围栏软件(SDK 内)地理围栏评估

可选依赖项:Play Integrity(设备证明)

如果您使用 Tracelet 的 设备证明 功能 (AttestationConfig),则 Android 一方通过 Google Play Integrity 生成其加密令牌。一样 play-services-location,此依赖项未捆绑 - 仅当您添加它时 启用认证:

// android/app/build.gradle.kts dependencies { implementation("com.google.android.play:integrity:1.6.0") }

它是可选的,并且证明会优雅地降级。 没有 Play Integrity 依赖关系,Tracelet 中的其他所有内容都正常工作 - 只有证明受到影响: AttestationConfig(enabled: true) 记录警告和 Tracelet.getAttestationToken() 返回 null 而不是令牌,而不是崩溃。仅当您满足以下条件时才添加依赖项 启用证明并需要在 Android 上进行 Play 完整性判定。请参阅 设备认证指南  用于完整的工作流程和服务器端验证。

必须是 implementation,而不是 compileOnly 里面的 Play Integrity 是 compileOnly Tracelet SDK(因此永远不会在不使用证明的应用程序上提供或强制使用它)。如果 您无需将依赖项添加到 app 模块即可启用证明,如下所示 implementation,类在运行时不存在,并且证明会默默返回 null


权限和清单设置

当您编译应用程序时,Tracelet 会自动将必要的权限注入到 AndroidManifest.xml 中。默认情况下,它要求:

  • ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION(跟踪所需)
  • ACCESS_BACKGROUND_LOCATION(应用程序关闭时跟踪所需)
  • FOREGROUND_SERVICE & FOREGROUND_SERVICE_LOCATION(连续后台执行所需)
  • ACTIVITY_RECOGNITION(智能运动检测引擎所需)
  • POST_NOTIFICATIONS(Android 13+ 前台服务 UI 必需)
  • SCHEDULE_EXACT_ALARM(精确周期模式跟踪所需)

删除未使用的权限(清单合并)

如果您的应用不需要特定功能(例如,您的客户端不需要运动检测,或者您不使用周期模式),您可以在 应用级别 AndroidManifest.xml (android/app/src/main/AndroidManifest.xml) 中使用 Android 清单合并 tools:node="remove" 指令强制删除权限。

Tracelet 的本机代码受到 checkSelfPermission() 的完全保护。 缺少权限将触发正常回退,而不是崩溃。

许可删除后的效果 (tools:node="remove")
不翻译迟到安全。 回到基本的仅加速度计运动检测。 onActivityChange 流不会触发(无步行/跑步/驾驶分类)。
不翻译迟到安全。 当应用程序完全后台运行或滑开时,Android 10+ 将限制跟踪。
不翻译迟到安全。 定期模式退回到使用电池友好型但不精确的 WorkManager 计时器。
不翻译迟到安全。 前台服务持久通知在 Android 13+ 上隐藏。服务仍在运行。
不翻译迟到安全。 您将无法向操作系统请求电池优化豁免。
不传输迟到 / 不传输迟到对于仅地理围栏/仅定期应用程序是安全的。 删除它们会禁用连续前景跟踪 (start()),但标准地理围栏和定期模式继续工作。 连续后台跟踪所需
不传输迟到 / 不传输迟到不安全。 没有任何位置权限,Tracelet 无法获取位置。

Google Play 前台服务政策(2026 年 10 月 28 日生效)。 地理围栏 不再是前台服务位置允许的用例。如果您的应用程序使用 前台服务用于地理围栏,您必须删除

显现。 Tracelet 的标准地理围栏模式使用本机地理围栏 API 并执行 启动前台服务,因此仅地理围栏的应用程序是兼容的 - 只是 删除以下权限并保留 foregroundService.enabled = false。请参阅 地理围栏指南 了解详情。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!-- Geofence-only / periodic-only app: no continuous foreground tracking --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" tools:node="remove" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove" /> </manifest>

示例:删除运动和后台权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!-- Client doesn't want Activity/Motion tracking --> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove" /> <!-- Client only wants foreground tracking --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" /> <!-- Remove Exact Alarms --> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" tools:node="remove" /> </manifest>

自动 ProGuard / R8 规则

Tracelet 大量利用后台 Kotlin 服务、Rust 核心的 JNA 绑定以及反射 Pigeon 通道。如果这些被错误地混淆或缩小,当您的应用程序编译发布时,后台跟踪将默默失败。

您不需要为 Tracelet 手动配置 ProGuard。

tracelet_android 插件自动附带嵌入式 consumer-rules.pro。当您在发布模式下构建 Flutter 应用程序时,Android 的 R8 收缩器会自动提取这些规则,并确保所有必要的类(例如 HeadlessTaskServiceBootReceiver 和 Rust uniffi 绑定)在收缩后仍然存在。


场景一:送货司机(持续追踪)

探索的概念: 打瞌睡模式、前台服务、唤醒锁

问题

您的用户是披萨送货司机。他们把手机放进口袋,关掉屏幕。 15 分钟后,Android 进入 Doze 模式。它会关闭网络访问、推迟后台作业并严格限制 CPU 唤醒以节省电池。如果您的应用程序依赖于简单的计时器来获取 GPS,Android 将拒绝运行您的计时器。

Tracelet 如何解决:前台服务

前台服务告诉 Android:“嘿,我现在正在做一些非常重要的事情,用户完全意识到了这一点。不要杀我。”

android: tl.AndroidConfig( foregroundService: tl.ForegroundServiceConfig( enabled: true, channelName: 'Delivery Tracking', notificationText: 'Tracking your route to the customer', notificationOngoing: true, // User cannot swipe it away showNotificationOnPauseOnly: false, // Auto-hides when app is open actions: ['Pause', 'Complete'], // Adds interactive buttons to the notification ), )

通过在状态栏中显示持久通知,Tracelet 将应用程序的优先级提升到几乎与前台 UI 的级别。 Android 将让 Tracelet 无限期运行,绕过 Doze 模式限制。

自定义通知外观

要使持久通知与您的应用程序的品牌相匹配,您可以自定义图标和颜色:

android: tl.AndroidConfig( foregroundService: tl.ForegroundServiceConfig( enabled: true, notificationTitle: 'Delivery Mode', notificationText: 'Tracking your route...', notificationColor: '#0F9D58', // Your brand hex color notificationSmallIcon: 'ic_tracelet_icon', // The icon name notificationLargeIcon: 'ic_large_logo', ), )

重要图标规则:

  1. 文件位置: 图像文件必须放置在您的Android项目的drawable文件夹中(android/app/src/main/res/drawable/ic_tracelet_icon.png)。
  2. 小图标限制: Android 要求 notificationSmallIcon 完全平坦、透明且纯白色。如果您使用彩色徽标,Android 只会将其呈现为纯灰色或白色方块。
  3. 颜色属性: notificationColor 属性将为小图标的背景着色以匹配您的品牌。
🔔

Android 13+ 注意: 您必须在启动服务之前请求 POST_NOTIFICATIONS 权限,否则通知将被操作系统静默抑制。请参阅 Flutter SDK:权限 页面,了解如何从 Dart 代码中请求此权限。

跟踪时刷新通知 (updateNotification())

跟踪开始后需要更改通知 - 例如将标题从“途中”更新为“到达”、交换文本或在旅途中更改操作按钮?使用新的 ForegroundServiceConfig 调用 setConfig() 会保留这些值,但仅通知更改不会重新发布 Android 已显示的通知 - 新内容只会在不相关的服务重新启动或前台转换后出现。

v3.6.8 起,Tracelet.updateNotification() 会刷新实时通知,无需重新启动跟踪管道

// 1. Apply the new notification content. await Tracelet.setConfig( const tl.Config( android: tl.AndroidConfig( foregroundService: tl.ForegroundServiceConfig( notificationTitle: 'Arriving', notificationText: 'Your driver is 2 minutes away', ), ), ), ); // 2. Repost the active notification with the new content. await Tracelet.updateNotification();

设计上安全。 updateNotification() 永远不会重新启动跟踪,并且当前台服务当前未运行时(无需刷新),它是无操作。在 iOS 上,它会刷新正在运行的 Live Activity(当您通过 liveActivityConfig 选择加入一项时);在网络上,它是无操作的 - 因此相同的调用在每个平台上都是安全的。


场景 2:天气应用程序(定期跟踪)

概念探索: WorkManager 与 Exact Alarms

问题

您的用户下载了您当地的天气应用程序。您希望每 4 小时在后台唤醒一次,获取他们的位置,并下载本地天气预报。

想要持久的前台服务通知。用户会讨厌在抽屉里看到永久的“天气跟踪”通知。

Tracelet 如何解决这个问题:周期模式

Tracelet 可以使用 Android 的作业调度程序来短暂唤醒、修复并返回睡眠状态,而不是持续的服务。

android: tl.AndroidConfig( periodicUseForegroundService: false, periodicUseExactAlarms: true, // Uses AlarmManager instead of WorkManager )

两个调度程序

  1. 工作管理器(未翻译) 默认。它对电池非常友好。然而,Android 决定何时运行它。如果您要求它每 15 分钟运行一次,Android 可能会等待 45 分钟,并在用户解锁手机查看 Instagram 时运行它(称为“批处理”)。这是非常不精确的。

  2. 警报管理器(periodicUseExactAlarms: true 如果您绝对必须在特定时间准确唤醒设备,请使用此功能。它要求您在 android/app/src/main/AndroidManifest.xml 中声明 SCHEDULE_EXACT_ALARM 权限:

    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

注意:Google Play 严格审查此权限。仅当您的应用程序是闹钟、日历或绝对需要精确计时时才使用它。


场景 3:OEM 的侵略

探索的概念: 设置健康 API

问题

你做的一切都是对的。您有一个前台服务。但用户拥有一部小米手机。 MIUI 有一个专有的“电池保护程序”,可以在屏幕关闭 5 分钟后强制终止前台服务。

Tracelet 如何解决这个问题:自动缓解和提示

Tracelet 会在可能的情况下自动应用内部缓解措施,但有时用户必须在 OEM 的专有设置菜单中将您的应用程序列入白名单。

final health = await tl.Tracelet.getSettingsHealth(); if (health['isAggressiveOem'] == true) { // Automatically opens the manufacturer-specific settings screen // (e.g. Xiaomi Autostart, Huawei App Launch, Samsung Sleeping Apps) await tl.Tracelet.showPowerManager(); }

有关如何在 Flutter UI 中实现此功能的详细示例,请参阅诊断工具和电源管理 页面。