adb connect 连接 Android 设备的相关问题

最近在公司参与了一个 Android 机顶盒 App 开发,因为设备接口和驱动等原因,不像 Android 手机那样能方便地直接通过 USB 进行调试,只能通过 adb connect 以 TCP / IP 协议通信。

首先让 IT 给机顶盒分配了一个内网 IP ,并和 PC 接入同一局域网,然后在 PC 端运行 adb connect 192.168.xxx.xxx ,很快就连上了,跟 USB 调试几乎没有区别。

正好手中的 MI 2A USB 接口出故障了,同样尝试用 adb connect 连接,却总是失败。

StackOverFlow 找到了原因:需要开启设备 adb 服务 tcp 端口监听。

可能机顶盒是方便调试,默认开启了,大多数设备需要手动开启。

如果手机上装了终端类 App Better Terminal Emulator Pro,可以直接跑命令行,我们先设置adb端口监听并重启 adb 服务,然后查看监听状态:

adb connect 使用的 tcpip 端口默认是 5555 ,也可以自定义。可以看到该端口已处于 LISTEN 状态。

然后在 PC 端运行 adb connect 192.168.xxx.xxx 发现可以连接了(如果前面自定义了端口,IP 后要指明该端口号)。

但是如何保证手机重启后自动让 adb 服务监听 tcp 5555 端口?首先想到了直接修改系统根目录下的 init.rc 文件:

直接在文件最后面添加上面的脚本,重启手机后再次查看端口监听状态,发现并没有达到预期效果,而且打开 init.rc 文件也发现已经被还原。

难道是脚本添加的位置不正确?很快发现该文件中果然有启动 adbd 的语句,将设置端口监听的脚本插入该位置:

重启后发现依然不行。好吧,对底层没有深入研究过,这种方式先搁置。

只有在应用层通过 Java Runtime 间接操作底层了:接收 BOOT_COMPLETED 广播后启动 Service 达到开机启动的目的。

BroadcastReceiver 的注册就不赘述了,只列出开启 adb 服务 tcpip 端口监听的代码:

public static int enableAdbTcpipListening(int port) throws IOException, InterruptedException {
    Process process = Runtime.getRuntime().exec("su");
    DataOutputStream dos = new DataOutputStream((OutputStream) process.getOutputStream());
    dos.writeBytes("setprop service.adb.tcp.port " + port + "\n");
    dos.flush();
    dos.writeBytes("stop adbd\n");
    dos.flush();
    dos.writeBytes("start adbd\n");
    dos.flush();
    dos.writeBytes("exit\n");
    dos.flush();
    process.waitFor();
    return process.exitValue();
}

现在已经能成功通过 adb connect 无线调试,但也会发现其中存在的安全隐患:

你可以很容易连接并监听同一局域网内的所有已开启 adbd 服务的 Android 设备,无需得到授权,对方甚至不会收到任何提示!

虽然绝大多数手机默认是关闭的,但很多机顶盒却是默认就打开的。

而且很多手机还装了豌豆荚之类的 APP ,能通过 wifi 在 PC 客户端上更新应用,实际上也是通过这种 adb 方式连接的。

这样如果你同时安装了 PC 和 Android 客户端,甚至使用过 wifi 连接操作,则很有可能手机 adb 服务就是开启的,这种情况下手机就是很危险的,就算你关闭了这类 APP ,可能后台服务仍然在运行。

事实上 Android 4.2.2 已经通过 USB Debug Whitelist 修补了该漏洞 (参见官方文档):

如果你直接使用 adb connect ,虽然显示连接成功,但是你会发现设备是未授权的:

adb connect 192.168.128.100
connected to 192.168.128.100:5555
adb devices
List of devices attached
192.168.128.100:5555	unauthorized

你必须先通过 USB 连接 PC 和手机,手机会弹出一个 Dialog ,提示是否信任该 PC (将其 RSA 指纹加入手机的 USB Debug Whitelist ):

如果你的设备一开始就是 4.2.2 以上 ROM ,并且是第一次使用 USB 调试,当然没什么问题。

但如果你是从低版本 ROM 升级上来的(比如我的 MI 2A 就是最近一次更新才出现的这个授权问题),而且之前就已经开启并使用 USB 调试,需要先关闭 USB 调试再打开并重新连接,这样才会出现这个新的提示 PC RSA 指纹信息的 Dialog (换了电脑也会重新提示)。

4.2.2 以前是不会提示这个指纹信息的,而且只有在打开 USB 调试时提示,而不是区分 PC 设备。

最后,将 PC 端的 adb 也重启一下就 OK 了,尽情享受无线 Debug 的乐趣吧: