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

Android使用PARTIAL_WAKE_LOCK实现熄屏持续获取传感器数据问题求助

核心问题根因

问题来自两个常见实现错误和Android系统的后台传感器限制:

  1. 唤醒锁绑定在Activity生命周期上,而非持有传感器逻辑的前台服务,熄屏后Activity进入后台状态,唤醒锁可能被系统隐性回收导致失效
  2. 未在传感器注册时添加唤醒标记,Android 10及以上默认会截断后台应用的传感器事件推送,即便前台服务存活也不会触发回调

修复步骤

1. 调整唤醒锁持有逻辑

将唤醒锁的申请、释放逻辑完全迁移到前台服务中,不要绑定Activity生命周期。同时确认AndroidManifest.xml中已添加唤醒锁权限:

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

在前台服务的onCreate中申请唤醒锁,onDestroy中释放:

private var wakeLock: PowerManager.WakeLock? = null

override fun onCreate() {
    super.onCreate()
    // 申请唤醒锁
    wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
        newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::SensorWakeLock").apply {
            // 可设置最大持有时长避免内存泄漏,也可无参数手动释放
            acquire(1000 * 60 * 60 * 2L) // 最多持有2小时,按需调整
        }
    }
}

override fun onDestroy() {
    super.onDestroy()
    // 释放唤醒锁
    wakeLock?.takeIf { it.isHeld }?.release()
}

2. 迁移传感器注册逻辑到前台服务

禁止在Activity中注册传感器监听器,将所有传感器的注册、回调逻辑移至前台服务中,注册时必须添加SENSOR_FLAG_WAKE_UP标记,该标记会强制系统在熄屏状态下也向你的应用推送传感器事件:

private lateinit var sensorManager: SensorManager
private var linearAccelListener: SensorEventListener? = null

override fun onCreate() {
    super.onCreate()
    // 前面的唤醒锁逻辑省略
    sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    val linearAccelSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
    
    linearAccelListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
            // 此处可正常接收熄屏后的加速度数据
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]
        }
        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
    }

    // 注册传感器,核心是添加SENSOR_FLAG_WAKE_UP参数
    linearAccelSensor?.let {
        sensorManager.registerListener(
            linearAccelListener,
            it,
            SensorManager.SENSOR_DELAY_NORMAL, // 按需调整采样率
            0, // 报告延迟,按需调整
            SensorManager.SENSOR_FLAG_WAKE_UP
        )
    }
}

override fun onDestroy() {
    super.onDestroy()
    // 注销传感器监听器
    linearAccelListener?.let { sensorManager.unregisterListener(it) }
    // 前面的唤醒锁释放逻辑省略
}

3. 适配Android 12及以上版本

如果你的应用targetSdkVersion >=31,需要额外做两个配置:

  • 在AndroidManifest.xml的前台服务声明中添加传感器前台服务类型:
    <service
        android:name=".ForegroundService"
        android:foregroundServiceType="sensor"
        android:exported="false" />
    
  • 启动前台服务时,明确指定服务类型为传感器:
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SENSOR)
    } else {
        startForeground(NOTIFICATION_ID, notification)
    }
    

4. 处理厂商定制ROM限制

小米、华为、OPPO、vivo等国产ROM默认会限制应用后台使用传感器的权限,即便你完成了上述配置,也需要引导用户手动开启以下权限:

  • 关闭针对你的应用的电池优化,设置为「无限制」
  • 开启「后台活动权限」/「后台使用传感器权限」
  • 允许应用在后台弹出界面(部分ROM需要)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:48:00