知行手记首页

macOS 用 Chrome 调试 Android 手机

分类开发经验
> 适用场景:手机开了 USB 调试、也点了"允许",但 `chrome://inspect/#devices` 死活不显示设备;或者显示了却点不开任何页面。 > 本文给出一个**保证一遍过**的标准流程 + 一键脚本,并把最容易让人走弯路的几个坑重点标注出来,照着做基本不需要回头查。
macOS 用 Chrome 调试 Android 手机

一、先搞懂为什么会卡住(30 秒原理)

chrome://inspect 自己不会去发现手机,它完全依赖 adb(Android Debug Bridge)。所以问题一定出在下面两层之一:

  1. adb 层:手机没被 adb 认到(没授权 / 端口被抢 / USB 句柄丢失)。
  2. Chrome 调试通道层:手机虽被 adb 认到,但手机上的 Chrome 没创建调试套接字 chrome_devtools_remote,于是 chrome://inspect 列不出任何页面,本地转发也是空的。

经验结论:macOS 上 chrome://inspect 时好时坏是常态,最稳的办法不是跟它死磕,而是用 adb forward 直接把手机 Chrome 调试端口映射到本机,用 http://localhost:端口 调试——完全绕开 chrome://inspect 的设备发现机制。脚本默认就走这条路。


二、前置准备(一次性)

手机端

  1. 设置 → 关于手机 → 连续点击「版本号」7 次,解锁开发者选项
  2. 开发者选项 → 打开 USB 调试
  3. USB 连接模式切到 文件传输(MTP)(部分国产 ROM 在「仅充电」下不放行 adb)。

Mac 端

装 adb(已装可跳过):

brew install android-platform-tools
adb version   # 能输出版本号即成功

三、一键脚本:adb-inspect

把下面脚本存成 ~/ .local/bin/adb-inspect 并赋予可执行权限。它做了三件事:

  • 保证系统 adb 独占 5037 端口(避免和 Chrome 自带 adb 抢端口);
  • 等待手机授权,状态已是 device 就直接复用、不瞎重启(反复重启会搞丢 USB 句柄);
  • --forward 模式下:若手机 Chrome 没暴露调试套接字,就自动冷启动 Chrome 重建,再映射到本机空闲端口并自动打开调试页。
#!/bin/bash
# adb-inspect — 让 macOS 上 chrome://inspect 稳定识别 Android 手机
#
# 原理:macOS 上的 Chrome 自带一份旧版 adb,会与系统 adb 抢 5037 端口,
#       导致设备在 chrome://inspect 里时隐时现(unauthorized / 看不到)。
#       本脚本确保系统 adb 独占 5037,且必须在打开 Chrome 之前运行。
#
# 用法:
#   adb-inspect            确保系统 adb 独占 5037,打印设备状态
#   adb-inspect --forward  额外把手机 Chrome 调试端口映射到 http://localhost:9321 并自动打开
#   adb-inspect --help
set -u

ADB="$(command -v adb || echo /opt/homebrew/bin/adb)"
FORWARD=0
for arg in "$@"; do
  case "$arg" in
    --forward|-f) FORWARD=1 ;;
    --help|-h) echo "用法: adb-inspect [--forward]"; exit 0 ;;
  esac
done

# 若系统 adb 已在跑且设备已授权,直接复用,避免反复重启把 USB 句柄搞丢
if "$ADB" devices 2>/dev/null | awk 'NR>1{print $2}' | grep -qx device; then
  echo "✅ 已有系统 adb 服务且设备已授权,无需重启,直接复用。"
  "$ADB" devices -l
else
  echo "🔪 停止所有 adb 进程(含 Chrome 自带 adb)..."
  "$ADB" kill-server 2>/dev/null
  # 只杀进程名恰好为 adb 的(系统 adb 与 Chrome 自带 adb 同名),不会误杀本脚本
  pkill -x adb 2>/dev/null
  sleep 1

  echo "🚀 用系统 adb 启动服务(独占 5037 端口)..."
  "$ADB" start-server
fi

echo "⏳ 等待手机授权(最多 40 秒,请留意手机上的“允许 USB 调试”弹窗)..."
for i in $(seq 1 40); do
  if "$ADB" devices 2>/dev/null | awk 'NR>1{print $2}' | grep -qx device; then
    break
  fi
  printf "."
  sleep 1
done
echo

dev="$("$ADB" devices | awk 'NR>1 && $2=="device"{print $1; exit}')"

echo
echo "📱 当前设备:"
"$ADB" devices -l

if [ -z "$dev" ]; then
  echo
  echo "⚠️  仍未识别到已授权设备,请按顺序操作:"
  echo "   1) 拔掉 USB 线,等 2 秒,重新插上(强制 USB 重枚举)"
  echo "   2) 手机保持解锁、亮屏,弹出“允许 USB 调试”时点“允许”并勾选“一律允许”"
  echo "   3) 重跑一次: adb-inspect"
  exit 1
fi

if [ "$FORWARD" = "1" ]; then
  PORT=9321
  # 9321 通常为空闲端口,避开桌面 Chrome 已占用的 9222
  "$ADB" forward "tcp:$PORT" localabstract:chrome_devtools_remote 2>/dev/null
  sleep 1
  if curl -s --max-time 4 "http://localhost:$PORT/json/version" >/dev/null 2>&1; then
    echo
    echo "🔗 手机 Chrome 调试通道已建立 -> http://localhost:$PORT"
    echo "   正在为你打开调试界面…"
    open "http://localhost:$PORT" 2>/dev/null || echo "   (请手动打开 http://localhost:$PORT)"
  else
    echo
    echo "⚠️  手机 Chrome 未暴露调试套接字,正在冷启动 Chrome 以重建…"
    echo "    (原因:Chrome 常在 USB 调试开启前就已后台运行,导致未创建调试套接字)"
    "$ADB" shell am force-stop com.android.chrome 2>/dev/null
    sleep 2
    "$ADB" shell am start -n com.android.chrome/com.google.android.apps.chrome.Main 2>/dev/null
    sleep 5
    if curl -s --max-time 4 "http://localhost:$PORT/json/version" >/dev/null 2>&1; then
      echo "✅ 冷启动成功,调试通道已建立 -> http://localhost:$PORT"
      open "http://localhost:$PORT" 2>/dev/null || echo "   (请手动打开 http://localhost:$PORT)"
    else
      echo "❌ 仍无法建立。请确认:手机『开发者选项→USB 调试』已开、Chrome 已安装且能启动。"
      echo "   手动打开试试: http://localhost:$PORT"
    fi
  fi
fi

echo
echo "✅ 系统 adb 已就绪。现在打开/刷新 chrome://inspect/#devices 即可看到手机。"
echo "   (务必在本脚本之后才打开 Chrome;若之后再丢失,重跑 adb-inspect 即可,不要连跑多次)"

安装命令(存盘后执行一次即可):

mkdir -p ~/.local/bin
# 把上面脚本内容写入 ~/.local/bin/adb-inspect 后:
chmod +x ~/.local/bin/adb-inspect
# 确认 ~/.local/bin 已在 PATH(zsh 默认在)。验证:
which adb-inspect

四、保证一遍过:标准流程(照做即可)

顺序很重要:先跑脚本,再开 Chrome。这能从根本上避免端口冲突。

  1. 手机:USB 线连 Mac → 解锁、亮屏 → 若弹出「允许 USB 调试?」,点允许并勾选「一律允许使用这台计算机进行调试」
  2. Mac 终端跑(只跑一次,别连跑):
    adb-inspect --forward
    
    • 看到 ✅ 冷启动成功🔗 手机 Chrome 调试通道已建立 -> http://localhost:9321,脚本会自动打开浏览器。
  3. 浏览器自动打开 http://localhost:9321,页面里就是手机 Chrome 的所有标签页,每个都有 inspect 入口,效果等同 chrome://inspect,但稳定不受设备发现机制影响
  4. (可选)如果你就是想用 chrome://inspect:完成第 2 步后,再打开/刷新 chrome://inspect/#devices,设备会出现在列表里。

就这样,一遍过。


五、⚠️ 最容易踩的坑(重点标注,别走弯路)

下面这几条是 90% 人卡住的原因,已经按优先级排好:

⚠️ 坑 1(最高频,致命):Chrome 在「USB 调试开启 / USB 连上」之前就已后台运行

现象adb devices 显示 device(授权正常),但 chrome://inspect 空空如也,本地转发也打不开。 原因:Chrome 只在启动那一刻检测 USB 调试状态并创建调试套接字 chrome_devtools_remote。如果它早就在后台跑着,就压根没建这个套接字。 对策:用 adb-inspect --forward,脚本检测到套接字缺失会自动 am force-stop + 冷启动 Chrome 重建。不要手动去 chrome://inspect 硬等。 自查adb shell "cat /proc/net/unix" | grep chrome —— 没有 @chrome_devtools_remote 这一行,就是它没建。

⚠️ 坑 2(高频):adb 双服务抢 5037 端口

现象:设备时隐时现,unauthorized 和看不到交替出现。 原因:macOS 上的 Chrome 自带一份 adb,和系统 adb 同名,两份用不同密钥对,谁先占 5037 谁说了算。 对策:脚本已处理——先跑 adb-inspect 让系统 adb 独占 5037,之后才开 Chrome。绝不要「先开 Chrome、再折腾 adb」。

⚠️ 坑 3(隐蔽):本地转发端口别用 9222

现象adb forward tcp:9222 ...Address already in use,curl 空响应。 原因9222 常常被桌面版 Chrome 自己的远程调试端口占用,根本不是手机的。 对策:脚本已默认改用空闲端口 9321。自己手写命令时记得换端口(如 9321、9322…)。

⚠️ 坑 4(最容易被忽略):反复 kill/start adb 会搞丢 USB 句柄

现象:连跑几次 adb kill-server && adb start-server 后,adb devices 直接全空(连 unauthorized 都没了),但手机在 USB 总线上明明还在。 原因:adb 守护进程连续重启后,会丢失对 USB 设备的句柄,这种状态只能靠物理重插恢复。 对策只跑一次脚本,不要连跑多次。脚本也做了保护——已 device 就直接复用、不再重启。真遇到全空,拔插 USB 一次即可重枚举。

⚠️ 坑 5:授权弹窗没真正点到

现象adb devices 显示 unauthorized原因:弹窗在锁屏时一闪而过、或没勾「一律允许」、或点错了「取消」。 对策:手机「开发者选项 → 撤销 USB 调试授权」清空旧记录 → 拔插 → 亮屏点「允许」并勾选「一律允许」

⚠️ 坑 6:chrome://inspect 里「Discover USB devices」没勾

现象:用 chrome://inspect 时列表空白。 对策:打开 chrome://inspect/#devices,确认页面左上角 Discover USB devices 已勾选(默认勾,但可能被关掉)。

⚠️ 坑 7:USB 连接模式是「仅充电」

现象:部分国产 ROM 下 adb 不稳定或根本不认。 对策:下拉通知栏,把 USB 用途改成 文件传输(MTP)

💡 一个容易误判的点:adb devices -l 里设备信息显示成 product:darwin device:darwin 之类「不像手机」的字样,不一定是状态崩坏——某些机型(如锤子 aries)的内部代号本身就是这样,只要状态是 device、USB 调试能 shell 进去,就不影响调试,别被它带偏去瞎重启。


六、排错速查表

症状 根因 一句话解决
adb devices 空 / unauthorized 未授权或 USB 未重枚举 拔插 USB + 亮屏点「允许」并勾「一律允许」
adb devices 显示 device,但 inspect 空白、转发空 Chrome 早于 USB 调试启动,无调试套接字(坑 1) adb-inspect --forward 自动冷启动重建
设备时隐时现 adb 端口冲突(坑 2) 先跑脚本占 5037,再开 Chrome
forward 9222 报占用 9222 被桌面 Chrome 占(坑 3) 改用 9321
连跑 adb 后 devices 全空 USB 句柄丢失(坑 4) 拔插 USB 一次,别连跑脚本
chrome://inspect 空白 没勾 Discover USB devices(坑 6) 勾上 + 重开 Chrome

七、最小可用手动命令(不想用脚本时)

# 1) 确保系统 adb 独占 5037
adb kill-server && pkill -x adb; adb start-server

# 2) 手机亮屏点允许后,确认已授权
adb devices   # 应看到 xxxxxxxx device

# 3) 冷启动手机 Chrome(关键:重建调试套接字)
adb shell am force-stop com.android.chrome
adb shell am start -n com.android.chrome/com.google.android.apps.chrome.Main

# 4) 映射到本机空闲端口并打开
adb forward tcp:9321 localabstract:chrome_devtools_remote
open http://localhost:9321

一句话总结:手机开 USB 调试连 Mac → 跑一次 adb-inspect --forward(脚本会自动冷启动 Chrome 并建好通道)→ 浏览器开 http://localhost:9321 调试。全程不要连跑 adb、不要先开 Chrome、转发别用 9222——避开这三条,一遍就通。

以文字记录成长,以良知安顿内心

© 2026 知行手记