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

Android锁屏未充电时BLE通信被阻断的解决方案咨询

问题描述

设备已连接BLE且运行前台服务,但遇到以下异常:

  • 锁屏且未充电时,BLE通信完全被阻断;解锁亮屏或连接充电器后,积压的通信会立即恢复。
  • 日志显示锁屏期间BLE连接并未断开,但数据仅在亮屏后才会被接收;主机端在充电状态下能正常发送事件,排除了“主机仅亮屏时发数据”的可能。
  • 锁屏未充电时,主机发起的BLE通信会被直接忽略,直到亮屏或充电才恢复。
  • 已关闭所有可见的省电/电池优化选项,未申请Doze豁免(但了解应用不会立即进入Doze模式)。
  • 测试用的BLE数据接收提示音,通常在预期接收时间后60秒(偶尔20秒)、且亮屏/充电时才会触发。
  • 多设备验证:亮屏设备能正常接收BLE数据,锁屏设备完全无法接收;即使申请Doze豁免,问题依然存在。
  • 涉及设备:Samsung A23(Android 13)、Pixel 5(Android 14)。

前台服务启动代码:

val startIntent = Intent(context, XService::class.java)
ContextCompat.startForegroundService(context, startIntent)

服务通知代码:

val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
        this,
        SERVICE_NOTIFICATION_REQUEST_CODE, notificationIntent, FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, getString(R.string.notification_serviceChannelId))
        .setPriority(NotificationCompat.PRIORITY_LOW)
        .setContentTitle(notificationTitle)
        .setSmallIcon(notificationIconResourceId)
        .setContentIntent(pendingIntent)
        .setOngoing(true)
        .setAutoCancel(false)
        .setGroup(X_SERVICE_NOTIFICATION_GROUP_ID)
        .setGroupSummary(true)
        .build()

startForeground(X_SERVICE_NOTIFICATION_ID, notification)
解决建议

1. 提升通知及渠道优先级

当前通知用的PRIORITY_LOW会被部分厂商(如三星)判定为低优先级服务,进而限制资源。建议将优先级改为PRIORITY_HIGH,同时确保通知渠道的重要性设为高:

// 修改通知优先级
val notification = NotificationCompat.Builder(this, getString(R.string.notification_serviceChannelId))
        .setPriority(NotificationCompat.PRIORITY_HIGH) // 替换原PRIORITY_LOW
        // 其他配置保留
        .build()

// 创建通知渠道时设置高重要性(需要在初始化渠道时执行)
val channel = NotificationChannel(
    getString(R.string.notification_serviceChannelId),
    "BLE服务通知",
    NotificationManager.IMPORTANCE_HIGH
)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)

2. 声明BLE专用前台服务权限

针对Android 12+,在清单文件中添加FOREGROUND_SERVICE_CONNECTED_DEVICE权限,明确告知系统当前前台服务用于BLE设备连接,减少系统限制:

<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />

3. 定期发送BLE心跳包

锁屏后系统可能会暂停BLE回调,通过定时发送小型心跳包(10-30秒一次)可强制保持通信通道活跃:

private val heartbeatHandler = Handler(Looper.getMainLooper())
private val heartbeatRunnable = Runnable {
    if (bleDevice.isConnected) {
        sendHeartbeatPacket() // 实现自定义的心跳包发送逻辑
    }
    heartbeatHandler.postDelayed(heartbeatRunnable, 20000) // 20秒一次,可根据需求调整
}

override fun onCreate() {
    super.onCreate()
    heartbeatHandler.postDelayed(heartbeatRunnable, 20000)
}

override fun onDestroy() {
    heartbeatHandler.removeCallbacks(heartbeatRunnable)
    super.onDestroy()
}

4. 设置BLE连接优先级

在Gatt连接成功后,设置高优先级连接,让系统优先保障该BLE通道的资源:

// 连接成功后调用
bluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)

CONNECTION_PRIORITY_HIGH会缩短连接间隔,确保数据及时传输,同时降低系统暂停该连接的概率。

5. 移除通知分组设置

当前通知使用了setGroup和setGroupSummary,部分厂商可能会对分组通知的前台服务降低优先级。可暂时移除这两个配置测试:

val notification = NotificationCompat.Builder(this, getString(R.string.notification_serviceChannelId))
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setContentTitle(notificationTitle)
        .setSmallIcon(notificationIconResourceId)
        .setContentIntent(pendingIntent)
        .setOngoing(true)
        .setAutoCancel(false)
        // 移除setGroup和setGroupSummary配置
        .build()

6. 关闭厂商精细化省电设置

即使关闭了全局省电选项,部分厂商仍有应用级的隐藏限制,需引导用户手动操作:

  • 三星设备:设置 → 电池和设备维护 → 电池 → 后台使用限制 → 找到目标应用,设置为「允许后台活动」
  • Pixel设备:设置 → 电池 → 电池和应用省电 → 找到目标应用,关闭「省电模式」和「限制后台活动」

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:53:11