You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设备锁定/进入Doze模式时App后台持续运行及位置更新问题求助

解决Doze模式下后台位置持续更新问题

核心问题原因

Doze模式是Android为省电引入的机制,会限制后台进程的CPU、网络及定时器执行,普通Timer、未正确配置的JobScheduler都会被暂停,直到设备退出Doze状态。

可行解决方案

1. 使用Fused Location Provider实现后台位置更新

Google官方推荐的位置服务API针对后台场景做了优化,可在Doze模式下保持位置更新(需持有正确的位置权限),无需自行维护定时器:

  • 用FusedLocationProviderClient结合PendingIntent接收位置更新回调,系统会在位置变化时主动唤醒App
  • 配置LocationRequest时,合理设置更新间隔与优先级,平衡精度和功耗

示例代码:

// 初始化位置服务客户端
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)

// 构建位置更新请求
val locationRequest = LocationRequest.create().apply {
    interval = 60000 // 1分钟更新一次
    fastestInterval = 30000 // 最快30秒更新
    priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY // 平衡精度与功耗
}

// 创建PendingIntent用于接收位置更新广播
val intent = Intent(context, LocationUpdateReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    context,
    0,
    intent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

// 发起后台位置更新请求
fusedLocationClient.requestLocationUpdates(locationRequest, pendingIntent)

对应的广播接收器实现:

class LocationUpdateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val location = LocationResult.extractResult(intent)?.lastLocation
        location?.let {
            // 向服务器发送位置更新
            sendLocationToServer(it)
        }
    }
}

2. 正确配置WorkManager实现周期性任务

若需定时触发位置上传(而非依赖位置变化),使用WorkManager(替代旧版JobScheduler)并配置Doze兼容参数:

  • 设置setRequiresBatteryNotLow(false)允许低电量下执行
  • 设置setPersisted(true)确保设备重启后任务保留
  • 用PeriodicWorkRequest实现周期性任务调度

示例代码:

val periodicWork = PeriodicWorkRequestBuilder<LocationUploadWorker>(15, TimeUnit.MINUTES)
    .setRequiresBatteryNotLow(false)
    .setPersisted(true)
    .build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "LocationUpload",
    ExistingPeriodicWorkPolicy.KEEP,
    periodicWork
)

Worker类实现:

class LocationUploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        // 获取当前位置并上传至服务器
        getCurrentLocationAndUpload()
        return Result.success()
    }
}

3. 完成电池优化豁免全流程

仅跳转设置页面不够,需主动申请并确认豁免权限:

  • 在Manifest中添加权限:
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    
  • 检查当前豁免状态,未豁免则发起请求:
    val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
    val isIgnoring = powerManager.isIgnoringBatteryOptimizations(packageName)
    if (!isIgnoring) {
        val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
            data = Uri.parse("package:$packageName")
        }
        startActivity(intent)
    }
    

4. 禁用自行维护的定时器

Timer、Handler.postDelayed这类自定义定时器在Doze模式下会被系统暂停,必须依赖系统提供的位置回调或任务调度API才能保证可靠性。

内容的提问来源于stack exchange,提问作者Gopinath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:15:33