安卓手机adb快速切换5555端口

  1. Android 无 Root 固定 ADB 5555:Termux Widget 与 Tailscale 实践记录
    1. 实验目标与技术路线
    2. 原理验证
    3. 手机端实现
    4. Termux:Widget 启动脚本
    5. 最终操作流程与结论

Android 无 Root 固定 ADB 5555:Termux Widget 与 Tailscale 实践记录

实验目标与技术路线

目标是在无 Root 的 Android 手机上,将系统无线调试产生的随机 ADB 端口切换为固定的 TCP 5555,并借助 Tailscale 的稳定设备名,使 Ubuntu 或 macOS 最终只需执行:

adb connect oppo-reno6-pro-5g:5555

实验环境为 Android 13 / ColorOS、Termux、Termux:Widget、Termux:API、Android Platform Tools 和 Tailscale。整体链路如下:

Android 无线调试随机端口
        ↓
Termux 连接本机 adbd
        ↓
adb tcpip 5555
        ↓
adbd 固定监听 TCP 5555
        ↓
Tailscale 提供稳定主机名
        ↓
Ubuntu/macOS 直接连接

这里需要明确两个职责:Termux 脚本负责启动 5555,Tailscale 只负责网络可达性和稳定名称。Tailscale 不会主动开启 ADB 服务。


原理验证

Android 无线调试存在两个不同端口。“使用配对码配对设备”页面显示的是一次性配对端口,只用于:

adb pair 192.168.51.138:36435 057615

无线调试主页显示的 IP address & Port 才是实际连接端口,例如:

adb connect 192.168.51.138:36555

完成连接后,可将 adbd 切换到固定端口:

adb -s 192.168.51.138:36555 tcpip 5555

验证结果如下:

adb connect 192.168.51.138:5555
adb devices -l

当设备状态为 device 时,说明当前 ColorOS 允许从无线调试 TLS 模式切换到传统 TCP ADB 模式。

随后开启手机和电脑上的 Tailscale,测试稳定设备名:

adb connect oppo-reno6-pro-5g:5555

连接成功说明完整链路成立,后续不再依赖手机不断变化的 Wi-Fi 地址。

手机端 Termux 也应验证本机回环连接:

adb connect 127.0.0.1:5555
adb -s 127.0.0.1:5555 get-state

预期输出:

device

脚本应始终使用明确的 ADB serial,例如:

adb -s 127.0.0.1:5555 get-state

而不是直接运行不带 -sadb shelladb tcpip。这是因为 Termux 中可能同时出现 127.0.0.1:5555emulator-5554,未指定设备时可能触发 more than one device/emulator


手机端实现

Termux 中安装依赖:

pkg update
pkg install android-tools termux-api

可选安装 jq,用于可靠解析 Termux:API 返回的 JSON:

pkg install jq

Android 端还需要安装 Termux、Termux:Widget 和 Termux:API。三个应用建议来自同一软件源,避免插件签名不一致。

主逻辑脚本位于:

$HOME/bin/adb5555

它至少需要支持以下接口:

adb5555 --status
adb5555 --port 43099
adb5555 --endpoint 127.0.0.1:43099

主脚本的职责是检查 127.0.0.1:5555、连接当前无线调试端口、执行 adb tcpip 5555,并在切换后再次验证固定端口。

本机实际测试表明,ColorOS 上:

getprop service.adb.tls.port

返回为空,而:

adb mdns services

也无法发现 _adb-tls-connect._tcp。因此无法可靠地自动获取重启后产生的新端口,但显式传入端口可以成功:

adb5555 --port 43099

实验输出为:

[adb5555] 正在验证无线调试端点:127.0.0.1:43099。
[adb5555] 已连接端点:127.0.0.1:43099,正在执行 adb -s 127.0.0.1:43099 tcpip 5555。
[adb5555] ADB 5555 已经可用。

因此问题仅存在于“端口自动发现”,不影响配对授权、ADB 自连接以及 tcpip 5555


Termux:Widget 启动脚本

桌面启动脚本保存为:

$HOME/.shortcuts/ADB-5555

当前实现如下:

#!/data/data/com.termux/files/usr/bin/bash

set -Eeuo pipefail

readonly MAIN="$HOME/bin/adb5555"
readonly LOG_FILE="$HOME/.cache/adb5555-widget.log"

has_termux_api_app() {
    /system/bin/pm path com.termux.api >/dev/null 2>&1
}

notify() {
    local message="$1"

    if has_termux_api_app && command -v termux-toast >/dev/null 2>&1; then
        termux-toast "$message" >/dev/null 2>&1 || true
    fi
    printf '%s\n' "$message"
}

write_log() {
    mkdir -p "${LOG_FILE%/*}"
    printf '%s\n' "$1" > "$LOG_FILE"
}

if "$MAIN" --status >/dev/null 2>&1; then
    notify 'ADB 5555 已经可用。'
    exit 0
fi

if ! has_termux_api_app || ! command -v termux-dialog >/dev/null 2>&1; then
    notify '缺少 Termux:API 应用。请安装该 Android 应用,并在 Termux 执行:pkg install termux-api'
    exit 1
fi

result="$(
    termux-dialog text \
        -t 'ADB 无线调试端口' \
        -i '请输入“无线调试”主页显示的 IP:端口,例如 172.19.0.1:37405' \
        2>/dev/null || true
)"

if command -v jq >/dev/null 2>&1; then
    port="$(
        printf '%s' "$result" |
        jq -r \
            'if .code == 0 and (.text | type == "string")
             then .text
             else empty
             end' \
            2>/dev/null || true
    )"
else
    port="$(
        printf '%s' "$result" |
        tr -d '\r\n' |
        sed -n \
            's/.*"text"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p'
    )"
fi

if [[ "$port" == *:* ]]; then
    command=(--endpoint "$port")
elif [[ "$port" =~ ^[0-9]+$ ]] &&
     (( port >= 1024 && port <= 65535 )); then
    command=(--port "$port")
else
    write_log "对话框返回内容:$result"
    notify 'ADB 端点无效或已取消。请输入 IP:端口,或仅输入端口。'
    exit 1
fi

if output="$("$MAIN" "${command[@]}" 2>&1)"; then
    write_log "$output"
    notify 'ADB 5555 已启动。'
    exit 0
fi

write_log "$output"
notify 'ADB 启动失败;请在 Termux 查看 ~/.cache/adb5555-widget.log'
exit 1

该脚本采用严格 Bash 模式,并将核心逻辑委托给 $HOME/bin/adb5555。启动时首先调用 --status 检查固定端口,若 5555 已可用则直接退出,保证重复点击不会反复重启 adbd。

当固定端口不可用时,脚本检查 Termux:API 应用与 termux-dialog 命令,并弹出无线调试端口输入框。

termux-dialog 返回 JSON。脚本优先使用 jq 解析,在未安装 jq 时退回 sed;输入既可以是完整的 IP:端口,也可以只输入端口号。纯端口必须处于 1024~65535 范围内。

最终,Widget 根据输入调用:

adb5555 --port 43099

或者:

adb5555 --endpoint 192.168.51.138:43099

执行结果会保存到:

$HOME/.cache/adb5555-widget.log

成功时显示 Toast,失败时保留完整日志供排查。

完成后设置权限并检查语法:

chmod 700 "$HOME/bin/adb5555"
chmod 700 "$HOME/.shortcuts/ADB-5555"

bash -n "$HOME/bin/adb5555"
bash -n "$HOME/.shortcuts/ADB-5555"

随后在 Android 桌面添加 Termux:Widget,并选择 ADB-5555


最终操作流程与结论

手机每次重启后,固定 5555 通常会失效。实际操作流程为:

开启开发者选项中的“无线调试”
        ↓
查看主页中的 IP address & Port
        ↓
点击桌面的 ADB-5555 Widget
        ↓
输入冒号后的端口,例如 43099
        ↓
脚本连接 127.0.0.1:43099
        ↓
脚本执行 adb tcpip 5555
        ↓
开启 Tailscale

电脑端最终只需运行:

adb connect oppo-reno6-pro-5g:5555

建议进一步使用明确的 serial:

adb -s oppo-reno6-pro-5g:5555 shell
adb -s oppo-reno6-pro-5g:5555 install app.apk
adb -s oppo-reno6-pro-5g:5555 push file.txt /sdcard/Download/

本实验说明,无 Root 环境下仍可以利用 Android 原生无线调试完成授权,再由 Termux 将 adbd 切换至固定 5555。对于无法通过 getprop 或 mDNS 自动发现随机端口的厂商系统,使用 Termux:API 弹窗接收端口,是一种比全端口扫描更稳定、透明且易维护的折中方案。

该方案不得将 5555 映射到公网。推荐仅在可信局域网或个人 Tailscale Tailnet 内使用。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 kipleyarch@gmail.com