只在车载无线充电板上充电特别慢时,元凶是发热而不是手机设置 —— 这是用 adb 实测的记录。对象: Galaxy S25+ (SM-S936N, Android 16 / One UI 8.5) + Audi A5 原厂无线充电板 + 同时使用无线 Android Auto。
要点 —— 手机设置没有一处是错的。是手机从大约 38°C 起自己削减充电电流。
在桌上、走数据线、开着空调的室内,电池一到 38.5°C,输入上限就从 1500 降到 1000 mA,充电上限从 3456 降到 1800 mA。温度降下来就全部恢复。车厢里这个温度是常态 —— 无线 AA 让 Wi-Fi 一直在发,无线充电在线圈里生热,仪表台上的充电板又不通风。
下面所有诊断命令都是只读的。不会改动设备设置。
"无线充电慢"可能是两件事叠在一起。一个是手机和充电板协商出多少瓦,另一个是协商好的功率被手机因为发热削掉多少。前者是充电板的问题,后者是手机的问题。要分清就得分开测。
这次确凿抓到的是后者。前者还没抓到(见后面"还不清楚的部分")。
有一个观察定了方向。在家里和办公室的无线充电器上,同一部手机充电速度正常。 同一部手机、同样的无线方式,只在车里慢,那差别就不在手机设置上,而在热或者协商功率上。
桌上 / 有线(Mac USB)/ 开空调的室内 / 电池 98%。解析内核每 10 秒输出一次的 !@new_battery_dump 日志。
| 时刻 | 输入上限 | 充电上限 | 电池温度 | 表面(SKIN)温度 | 发生了什么 |
|---|---|---|---|---|---|
| 09:56:52 | 1500 | 3456 | 38.1 | 37.3 | 基准 |
| 09:57:02 | 1500 | 1800 | 38.3 | 39.7 | 表面超过 38°C,充电上限被砍到一半以下 |
| 09:57:12 | 1200 | 1800 | 38.5 | 39.3 | 输入上限也被削 |
| 09:59:14 | 1000 | 2000 | 38.1 | 37.8 | 输入上限累计降了 33% |
| 10:03:38 | 1000 | 3456 | 37.7 | 36.8 | 温度降下来,充电上限恢复 |
| 10:03:48 | 1500 | 3456 | 37.6 | 36.7 | 输入上限也恢复 |
归纳一下:
这个数值和手机自己带的热阈值是对得上的。
adb shell dumpsys thermalservice
SKIN mHotThrottlingThresholds = [38.0, 40.0, 42.0, 45.0, 47.0, 60.0, 90.0]
BAT mHotThrottlingThresholds = [NaN, NaN, NaN, NaN, NaN, 55.0, 85.0]
表面温度的第一档是 38.0°C。对手机表面来说这个值相当低,而充电在这里就已经开始被削了。
调查中偶然抓到了一段 4 分钟的无线充电区间 —— 来自 dumpsys battery 的事件环形缓冲区。
| 时刻 | 电流 | 温度 | misc_event |
|---|---|---|---|
| 09:45:50 | 约 1.05 A | 37.6 | 0x10000 |
| 09:45:51 | 约 1.23 A | 37.7 | 0x10040 |
| 09:45:52 | 约 1.24 A | 37.8 | 0x10040 |
| 09:46:02 | 约 0.62 A | 38.6 | 0x10040 |
12 秒内电流正好腰斩,而且和温度上升严丝合缝(37.8 → 38.6°C,1.24 → 0.62 A)。有线上看到的 38°C 分界线,在线圈上照样起作用。车里起始温度本来就更高,所以这个下降来得更快、掉得更深。
还有一点。misc_event 的 0x40 位只在无线充电时置起。 有线区间一次都没出现过。看起来是三星 sec_battery 驱动里的无线专用位 —— 异物检测(FOD)或者线圈检测中断一类 —— 但还没确定。看不到内核头文件,/sys/class/power_supply 也被权限挡住了。
解读要小心:这段区间电池是 99~100%。接近满电时电流本来就低,所以不要看绝对值(1.2 A ≈ 5 W)就断定"无线协商到了 5W"。 但 12 秒腰斩没法用电量变化解释,它只跟温度对得上。
车厢里凑齐了超过 38°C 所需的一切条件。
| 因素 | 效果 |
|---|---|
| 无线 Android Auto | 通过 Wi-Fi Direct 5GHz 不停投屏。AP 和基带一刻不歇。就算在桌上也能看到 AP 49.7°C / PA 49.1°C |
| 无线充电本身 | 线圈会发热。效率大约 70~80%,而数据线约 95%,差额都变成了热 |
| 七月的车厢 + 不通风的仪表台充电板 | 热量无处可去 |
三样叠起来,38°C 在起步后就会突破,之后一直停在最低档。
如果充电板协商的功率也低,情况会更糟。协商 5W,被热削掉一半,实际就只有 2~3W。跑无线 AA 的耗电差不多就是这个量级 —— 于是就出现放在充电器上电量却在掉的情况。
"无线充电慢"通常会怀疑的项目,全都是正常的。得先排除这些,才能往热的方向走。
adb shell dumpsys battery
| 检查项 | 值 | 判定 |
|---|---|---|
| 无线快充设置 | mWirelessFastChargingSettingsEnable: true |
已开启 |
| 无线快充支持 | FEATURE_WIRELESS_FAST_CHARGER_CONTROL: true |
支持 |
| 无线电池共享 | ps:false |
关闭 —— 手机没有在往外送电 |
| 电池损耗 | mSavedBatteryAsoc: 99、BSOH 100.00 |
良好(使用 1 年 5 个月) |
| 学习容量 | 4700 mAh(保持设计值) | 良好 |
| USB 口潮湿检测 | mIsHiccupState=false |
正常 |
如果无线电池共享是开着的,手机放在充电板上反而会试着往外送电,几乎充不进去。这是第一个该看的项目,不过这里是关着的。
手机壳是 PC 材质 0.8 mm,不含金属。这个厚度不会妨碍无线充电。
无线路径上手机和 Audi 充电板实际协商出多少瓦,没能抓到。 所以到底是发热就能解释全部,还是底下还叠着一个"一开始就只协商到 5W"的问题,目前还分不出来。
dumpsys battery报的是Max charging current: 0,它不填这个值。这样一来内核输出的!@new_battery_dump就是唯一的路子,而拿到它并不容易 —— 见下文。
misc_event 的 0x40 位是不是 FOD(异物检测)也还没定。如果是 FOD,原因的结构就变了。
这是本文最值得复用的部分。
三星把 logcat 环形缓冲区硬限制在 5 MiB。要更大会被拒绝。
$ adb logcat -b main -G 64M
MAX log buffer size is 5 MiB. So set it to 5 MiB
这部手机日志每分钟堆约 1.5 MiB,所以缓冲区大概 14 分钟就被覆盖。实际上,调查开始时还留着的最早一条电池日志,就是插上 USB 那一刻的 —— 之前那段行驶记录早就没了。
同一台设备的无线 AA 断连调查也撞上了同一个上限。这个 5 MiB 限制会卡住所有想抓行驶日志的尝试,无论你要的是电池还是 Wi-Fi。
只筛 BatteryDump 标签,直接写到手机里的文件。过了筛选之后 10 秒一行(约 200 B),所以开一小时车只有 72 KB。没有被覆盖的余地。
# 开车前(在 USB 连着的状态下执行)
adb shell "setsid nohup logcat -v time -s BatteryDump:E \
-f /sdcard/wcharge.log -r 2048 -n 4 >/dev/null 2>&1 &"
# 确认还活着
adb shell 'for p in $(pidof logcat); do \
grep -q BatteryDump /proc/$p/cmdline && echo $p; done'
setsid 会把它从 shell 会话里摘出来挂到 init(PPID 1)下,所以拔掉数据线它还在跑。重启会死,手机重启过就要重新拉起来。
# 开完车 —— 先让它正常退出,把缓冲里剩下的落到文件里
adb shell "kill -TERM $(adb shell pidof logcat)"
adb pull /sdcard/wcharge.log
# 顺手把不受环形缓冲区影响的信息也取走
adb shell dumpsys battery > battery.txt
logcat -f是按 4 KB 块 flush 的。也就是说最后 2~3 分钟还没落到文件里。 取之前用kill -TERM让它正常退出,剩下的就会写进文件。
有一个坑。logcat 的 -t N 是在标签筛选之前生效的。
# 几乎总是 0 行 —— 变成了"最后 4 行里属于 BatteryDump 的那些"
adb logcat -d -t 4 -s BatteryDump:E
# 要这么写 —— 先按标签筛,再在后面切
adb logcat -d -v time -s BatteryDump:E | grep new_battery_dump | tail -4
想实时看的话,别用流式,把上面这条命令每几秒重复一次更好。用 adb logcat -s ... | while read 接管道的话,logcat 会做 4 KB 块缓冲 —— 筛过的日志一次只出 200 B,结果是200 多秒什么都不出来。
测量要在电池 50~70% 的区间做。 90% 以上处于恒压阶段,电流本来就低,分不出慢的原因。这次调查正好撞上了这个限制。
!@new_battery_dump 字段对照以 E/BatteryDump 标签每 10 秒输出一次。逗号分隔,按 awk 的 1-based 计。
4339,1081,1500,3456,98,372,352,392,372,0,363,386,0,Charging,NO_CHARGING,Normal,Good,PDIC,...
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18
| 索引 | 含义 | 怎么确认的 |
|---|---|---|
$1 |
电池电压 (mV) | 和 BSOHChargingDataCollector 日志的 voltage:4.339 一致 |
$2 |
当前电流 (mA) | 和同一日志的 current:1.084375 一致 |
$3 |
输入电流上限 (mA) | 观测到随温度在 1500→1000 之间变动 |
$4 |
充电电流上限 (mA) | 观测到 3456→1800 变动 |
$5 |
电量 (%) | 和 soc:0.98 一致 |
$6 |
电池温度 (0.1°C) | temperature:37.2 = 372 一致 |
$7 |
USB 温度 | 和 thermalservice 的 USB 35.2 = 352 一致 |
$8 |
充电 IC 温度 | — |
$11 |
表面(SKIN)温度(推测) | 接近 thermalservice 的 SKIN 36.2 ≈ 363 |
$14 |
充电状态 | Charging / Full |
$18 |
线缆类型 | 有线 PD 上确认为 PDIC。无线时的值未知 |
$24 |
current_event 位 |
有线 0x20008000,无线 0x40000000 系 |
$25 |
misc_event 位 |
只有无线时 0x40 会置起 |
$9、$11 是看它们和 thermalservice 的值同步变动推测出来的,并未确定。
| 无线区间里观察到的 | 结论 |
|---|---|
| 输入上限一开始就低,且与温度无关地保持不变 | 充电板协商功率的上限 |
| 输入上限起初较高,随温度上升逐级下降 | 是热在削 |
| 两者都有 | 复合 |
misc_event 的 0x40 比正常充电器上置起得更持续 |
怀疑 FOD |
cable_type 和正常充电器不是同一个字符串 |
协商协议的差异 |
在同样的电量区间,用家里或办公室的充电器测一次,对比立刻就出来了。
按效果从大到小。
手机壳没有换的理由。不含金属的 0.8 mm 不会妨碍无线充电。
电池保护模式(自适应,80% 上限)主要在睡眠充电时段生效,不太可能是行驶中充电慢的主因。优先级低。
| 项目 | 怎么判定的 | 本例结果 |
|---|---|---|
| 无线快充关闭 | mWirelessFastChargingSettingsEnable |
不是 —— 是开着的 |
| 无线电池共享开启 | ps: 字段 |
不是 —— 是关着的 |
| 电池损耗 | ASOC / BSOH | 不是 —— 99% / 100% |
| 手机壳干扰 | 材质与厚度 | 不是 —— 0.8 mm,无金属 |
| 热在削电流 | !@new_battery_dump 的输入/充电上限变动 |
实测确认 —— 38°C 时输入 −33%、充电 −48% |
| 充电板协商功率上限 | 无线区间的输入上限 | 未确定 —— 缓冲区被覆盖,没抓到 |
| FOD(异物检测) | misc_event 的 0x40 位 |
未确定 —— 只在无线时置起,含义不明 |
从设备里导出的日志可能夹带账号和设备标识。分享前先检查。