fix: 打勾检测改用全局蓝色角标计数,不受列表滚动漂移影响
根因:等待期间列表轻微滚动(约50px),用点击时的旧行坐标检测打勾 位置偏移,导致明明已打勾却检测不到0/6,误判为下载失败。 修复: - 新增 count_checked_badges():扫描整屏蓝色角标总数,不依赖行坐标 - 等待逻辑改为:点击前记基线→等待期间统计当前总数→ 增量>=点击数即完成 - 重试逻辑同步改用全局计数
This commit is contained in:
+45
-24
@@ -346,6 +346,26 @@ def get_checked_cells_dynamic(png_path, row_centers):
|
||||
return checked
|
||||
|
||||
|
||||
def count_checked_badges(png_path):
|
||||
"""统计整屏已打勾(蓝色角标)的卡片数量,不依赖行坐标。
|
||||
等待期间列表可能轻微滚动,用绝对坐标检测打勾会偏移,
|
||||
改为直接扫描整屏蓝色角标总数,不受行位置漂移影响。"""
|
||||
try:
|
||||
with Image.open(png_path) as img:
|
||||
img = img.convert("RGB")
|
||||
w, h = img.size
|
||||
cnt = 0
|
||||
# 扫描卡片区域内所有可能的角标位置(3列 × 多行)
|
||||
for gx in THUMB_X:
|
||||
for cy in range(ROW_Y0 + 100, ROW_Y1, ROW_PITCH):
|
||||
bx, by = gx + BADGE_OFFSET[0], cy + BADGE_OFFSET[1]
|
||||
if count_blue_pixels(png_path, bx, by) >= BLUE_THRESHOLD:
|
||||
cnt += 1
|
||||
return cnt
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
def launch_app():
|
||||
"""从头启动 App,等待 618 开屏广告自动关闭后回到首页。
|
||||
用 am start -S 强制重启主 Activity(比 monkey 更可靠:避免之前残留的
|
||||
@@ -731,40 +751,40 @@ def tap_all_thumbnails(baseline, max_rounds=300, poll_interval=4, max_wait_per_r
|
||||
# 关键:等这一轮点击的卡片全部显示打勾(下载完成)再滚动。这样滚动
|
||||
# 留下的重叠行必然是打勾状态,下一轮开头 get_checked_cells 会跳过它们,
|
||||
# 从根上消除"重叠行还没下完就被重复点击"这个唯一的重复来源。
|
||||
print(f" 轮 {r+1}: 等待刚点击的 {len(tapped_cells)} 个卡片全部打勾(最多 {max_wait_per_round}s)...")
|
||||
baseline_checked = count_checked_badges(grid_shot)
|
||||
target_checked = baseline_checked + len(tapped_cells)
|
||||
print(f" 轮 {r+1}: 等待刚点击的 {len(tapped_cells)} 个卡片全部打勾(基线 {baseline_checked},目标 {target_checked})...")
|
||||
waited = 0
|
||||
pending = list(tapped_cells)
|
||||
done = 0
|
||||
while waited < max_wait_per_round:
|
||||
time.sleep(poll_interval)
|
||||
waited += poll_interval
|
||||
ensure_not_anr() # 等待期间 App 也可能卡死,同样要检测
|
||||
ensure_not_anr()
|
||||
wait_shot = screenshot("/tmp/_waitchk.png")
|
||||
# 等待期间未滚动,行位置不变,复用本轮 row_centers 复检这些格子
|
||||
chk = get_checked_cells_dynamic(wait_shot, row_centers)
|
||||
pending = [c for c in tapped_cells if not chk.get(c)]
|
||||
if not pending:
|
||||
current_checked = count_checked_badges(wait_shot)
|
||||
done = current_checked - baseline_checked
|
||||
if done >= len(tapped_cells):
|
||||
break
|
||||
done = len(tapped_cells) - len(pending)
|
||||
pending = len(tapped_cells) - done
|
||||
total = get_remote_new_file_count(baseline)
|
||||
if pending:
|
||||
# 超时未打勾:先不重试点击(队列满时重试无效),再等一轮让正在下载的完成
|
||||
print(f" 轮 {r+1}: 等待 {waited}s 后 {done}/{len(tapped_cells)} 个已打勾,"
|
||||
f"仍有 {len(pending)} 个未完成,继续等待一轮...")
|
||||
# 第二轮等待:不重试点击,让正在下载的完成
|
||||
print(f" 轮 {r+1}: 等待 {waited}s 后 {done}/{len(tapped_cells)} 个已打勾,继续等待...")
|
||||
wait2_waited = 0
|
||||
while wait2_waited < max_wait_per_round:
|
||||
time.sleep(poll_interval)
|
||||
wait2_waited += poll_interval
|
||||
ensure_not_anr()
|
||||
w2_shot = screenshot("/tmp/_wait2.png")
|
||||
w2_chk = get_checked_cells_dynamic(w2_shot, row_centers)
|
||||
still_pending = [c for c in pending if not w2_chk.get(c)]
|
||||
if not still_pending:
|
||||
current2 = count_checked_badges(w2_shot)
|
||||
done = current2 - baseline_checked
|
||||
if done >= len(tapped_cells):
|
||||
break
|
||||
if still_pending:
|
||||
# 两轮等待后仍未打勾,可能是点击没生效(落在间隙上)或队列满被拒绝
|
||||
# 再重试点击一次,然后等最后一轮
|
||||
print(f" 轮 {r+1}: 再等 {wait2_waited}s 后仍有 {len(still_pending)} 个未完成,重试点击...")
|
||||
for (gx, cy) in still_pending:
|
||||
pending = len(tapped_cells) - done
|
||||
if pending:
|
||||
# 两轮等待后仍未完成,重试点击所有未完成的卡片
|
||||
print(f" 轮 {r+1}: 再等 {wait2_waited}s 后仍有 {pending} 个未完成,重试点击...")
|
||||
for (gx, cy) in tapped_cells:
|
||||
adb("shell", "input", "tap", str(gx), str(cy))
|
||||
time.sleep(0.5)
|
||||
retry_waited = 0
|
||||
@@ -773,12 +793,13 @@ def tap_all_thumbnails(baseline, max_rounds=300, poll_interval=4, max_wait_per_r
|
||||
retry_waited += poll_interval
|
||||
ensure_not_anr()
|
||||
retry_shot = screenshot("/tmp/_retrywait.png")
|
||||
retry_chk = get_checked_cells_dynamic(retry_shot, row_centers)
|
||||
still_pending = [c for c in still_pending if not retry_chk.get(c)]
|
||||
if not still_pending:
|
||||
current3 = count_checked_badges(retry_shot)
|
||||
done = current3 - baseline_checked
|
||||
if done >= len(tapped_cells):
|
||||
break
|
||||
if still_pending:
|
||||
print(f" 轮 {r+1}: 三轮等待后仍有 {len(still_pending)} 个未完成,照常滚动(靠下游去重兜底)")
|
||||
pending = len(tapped_cells) - done
|
||||
if pending:
|
||||
print(f" 轮 {r+1}: 三轮等待后仍有 {pending} 个未完成,照常滚动(靠下游去重兜底)")
|
||||
else:
|
||||
print(f" 轮 {r+1}: 全部打勾完成")
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user