通过 ADB 连接到 Docker 容器中的 USB Android 设备
Connecting to a USB Android device in a Docker container via ADB
我创建了一个包含 Android SDK 的 Docker 图像,我正试图在容器 运行 中公开我的 Android phone图片。所以我使用 --privileged
标志并按如下方式安装 USB 设备:
$ docker run --privileged -v /dev/bus/usb:/dev/bus/usb -d -P my-android:0.0.1
但是,当我 运行 ADB 设备时,它没有显示 USB 设备:
ubuntu@d56b666be455:~/Android/Sdk/platform-tools$ ./adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
ubuntu@d56b666be455:~/Android/Sdk/platform-tools$
容器内的 lsusb 列出设备:
ubuntu@d56b666be455:~$ lsusb
...
Bus 002 Device 017: ID 04e8:6866 Samsung Electronics Co., Ltd GT-I9300 Phone [Galaxy S III] (debugging mode)
但该设备在主机上可见:
⇒ ./adb devices
List of devices attached
4d11abcd65b74045 device
主持人OS
$ uname -a
Linux ananya 3.16.0-33-generic #44~14.04.1-Ubuntu SMP Fri Mar 13 10:33:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Docker版本
$ docker --version
Docker version 1.5.0, build a8a31ef
可能是什么问题?
我不认为设备上的 ADB 守护程序 运行 可以连接到两个 ADB 服务器。尝试断开它与主机 ADB 的连接,然后将其连接到 Docker 容器的 ADB。
更新:
我最终使用 --privileged 和 -v 来映射整个 /dev/bus/usb
并修补 adb 以接受一个环境变量来指定根 USB 设备树 - /dev/bus/usb/001
等
这允许我们为相同 phone 的不同组的不同容器使用不同的 USB 总线,另一个环境变量补丁允许不同的 VID:PID 列表用于不同类型的 phone .
我们正在尝试将不同的 USB 总线分配给不同的 Docker 容器 运行ning TeamCity 客户端。
每个容器需要 ANDROID_ADB_SERVER_PORT 设置到不同的端口(因为我们没有使用隔离网络)。
主机不能 运行 adbd
,因为在任何给定时间只有一个 adbd
可以与 phone 对话。
每个容器都有 /dev/bus/usb/xxx
目录之一,因此我们可以将 phone 插入特定容器。
我们必须每隔几秒同步一次 /dev/bus/usb/xxx
目录,以允许热插拔和重新启动 - 只是主机上的一个 shell 循环 运行s tar cf devxxx.tar /dev/bus/usb/xxx
, docker cp
进行传输,然后 docker exec
在容器 /tmp
内解压,diff 检测要删除的节点,然后 mv -n
将新节点移入。
事实上,因为我们 运行 正在 Linux,我们可能只设置 udev 脚本,根据 Howto run a script when a USB device is pluged in .
虽然我也在尝试同样的事情,但我 运行 遇到了一些与此相关的其他问题,我想分享这些问题,以便其他人可以节省他们的时间:
问题一:容器中没有安装lsusb
在我的例子中 lsusb 没有安装,所以我用下面的命令安装它:
apt-get update
apt-get install usbutils
问题2:安装lsusb和ADB SDK后还是看不到设备
您需要使用 -v
选项重新启动您的容器,是的,不要忘记按照其中一个答案所述终止 ADB 服务器。
在主机上:
adb-kill server
docker run -ti -d --privileged -v /dev/bus/usb:/dev/bus/usb container_name
如果有人想从头开始,我已经写了一篇博客post:
这并没有回答您提出的确切问题,但确实解决了您试图完成的问题 - 从 adb 客户端连接到连接到 docker 主机的 android 设备 运行 在 docker 容器中。我为任何试图完成同样事情的人(就像我一样)包括这个。
adb 客户端支持 -H
选项,告诉它在哪里可以找到要连接的 adb 服务器。 Docker 支持主机名 "host.docker.internal",它始终映射到 docker 主机的 IP 地址。假设您的设备连接到 docker 主机,您可以执行以下操作让容器化的 adb 客户端连接到 docker 主机上的 adb 服务器 运行:
adb -H host.docker.internal devices
无需安装 USB 端口即可实现目标。
参考:https://developer.android.com/studio/command-line/adb
更新:
我最近了解到,在 18.0 及更高版本中,host.docker.internal 仅在 Docker for Mac 上受支持。
不好意思打扰了。但是我无法回答 this 问题所以我把它写在这里。
我正在使用 ubuntu:18.04 并尝试连接我的 Samsung Galaxy A3 2016 并使用 ADB 对其进行调试。设备未经授权,屏幕上没有弹出对话框!
我是如何解决问题的:
我很感兴趣问题是否仍然会在 Docker 容器中发生?答案是 "No!"。
在一个 Docker 容器中,我调用了以下内容:(这是本主题的答案:))
docker run --name android-adb -it -d --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu:16.04 bash
我下载了 platform-tools(使用 ADB 分发)。将其路径添加到环境中。并重新启动 bash
在 Docker 容器内重新启动 ADB 服务器并终止主机上的 ADB 服务器后。我发现智能手机屏幕上出现了确认对话框!
所以我认为在主机上问题出在 .android
目录中。只需将其移动到 .android-backup
。下一个 adb start-server
命令将创建一个新的。我还用最近的
替换了 platform-tools
文件夹
运行 只是 --privileged -v /dev/bus/usb:/dev/bus/usb
对我不起作用。
我尝试使用 -p 5037:5037
转发 adb 守护程序的监听端口,但这也没有帮助。
只有在我添加 --net host
后它才有效。
这意味着主机的网络接口暴露给 docker,所以如果你不介意的话就使用它。也许除了5037之外还有更多端口需要转发....
这对我有用。
- 将您的设备设置为 PPT 模式
- (可选)检查设备是否在本地可用
$ adb devices
I try with many options and only one works. Using --network
flag as the next example
- 运行 容器
$ docker run -it --net host ubuntu bash
输出:
List of devices attached
464e128 device
我使用了 this Dockerfile。适用于 flutter 项目
我创建了一个包含 Android SDK 的 Docker 图像,我正试图在容器 运行 中公开我的 Android phone图片。所以我使用 --privileged
标志并按如下方式安装 USB 设备:
$ docker run --privileged -v /dev/bus/usb:/dev/bus/usb -d -P my-android:0.0.1
但是,当我 运行 ADB 设备时,它没有显示 USB 设备:
ubuntu@d56b666be455:~/Android/Sdk/platform-tools$ ./adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
ubuntu@d56b666be455:~/Android/Sdk/platform-tools$
容器内的 lsusb 列出设备:
ubuntu@d56b666be455:~$ lsusb
...
Bus 002 Device 017: ID 04e8:6866 Samsung Electronics Co., Ltd GT-I9300 Phone [Galaxy S III] (debugging mode)
但该设备在主机上可见:
⇒ ./adb devices
List of devices attached
4d11abcd65b74045 device
主持人OS
$ uname -a
Linux ananya 3.16.0-33-generic #44~14.04.1-Ubuntu SMP Fri Mar 13 10:33:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Docker版本
$ docker --version
Docker version 1.5.0, build a8a31ef
可能是什么问题?
我不认为设备上的 ADB 守护程序 运行 可以连接到两个 ADB 服务器。尝试断开它与主机 ADB 的连接,然后将其连接到 Docker 容器的 ADB。
更新:
我最终使用 --privileged 和 -v 来映射整个 /dev/bus/usb
并修补 adb 以接受一个环境变量来指定根 USB 设备树 - /dev/bus/usb/001
等
这允许我们为相同 phone 的不同组的不同容器使用不同的 USB 总线,另一个环境变量补丁允许不同的 VID:PID 列表用于不同类型的 phone .
我们正在尝试将不同的 USB 总线分配给不同的 Docker 容器 运行ning TeamCity 客户端。
每个容器需要 ANDROID_ADB_SERVER_PORT 设置到不同的端口(因为我们没有使用隔离网络)。
主机不能 运行 adbd
,因为在任何给定时间只有一个 adbd
可以与 phone 对话。
每个容器都有 /dev/bus/usb/xxx
目录之一,因此我们可以将 phone 插入特定容器。
我们必须每隔几秒同步一次 /dev/bus/usb/xxx
目录,以允许热插拔和重新启动 - 只是主机上的一个 shell 循环 运行s tar cf devxxx.tar /dev/bus/usb/xxx
, docker cp
进行传输,然后 docker exec
在容器 /tmp
内解压,diff 检测要删除的节点,然后 mv -n
将新节点移入。
事实上,因为我们 运行 正在 Linux,我们可能只设置 udev 脚本,根据 Howto run a script when a USB device is pluged in .
虽然我也在尝试同样的事情,但我 运行 遇到了一些与此相关的其他问题,我想分享这些问题,以便其他人可以节省他们的时间:
问题一:容器中没有安装lsusb
在我的例子中 lsusb 没有安装,所以我用下面的命令安装它:
apt-get update
apt-get install usbutils
问题2:安装lsusb和ADB SDK后还是看不到设备
您需要使用 -v
选项重新启动您的容器,是的,不要忘记按照其中一个答案所述终止 ADB 服务器。
在主机上:
adb-kill server
docker run -ti -d --privileged -v /dev/bus/usb:/dev/bus/usb container_name
如果有人想从头开始,我已经写了一篇博客post:
这并没有回答您提出的确切问题,但确实解决了您试图完成的问题 - 从 adb 客户端连接到连接到 docker 主机的 android 设备 运行 在 docker 容器中。我为任何试图完成同样事情的人(就像我一样)包括这个。
adb 客户端支持 -H
选项,告诉它在哪里可以找到要连接的 adb 服务器。 Docker 支持主机名 "host.docker.internal",它始终映射到 docker 主机的 IP 地址。假设您的设备连接到 docker 主机,您可以执行以下操作让容器化的 adb 客户端连接到 docker 主机上的 adb 服务器 运行:
adb -H host.docker.internal devices
无需安装 USB 端口即可实现目标。
参考:https://developer.android.com/studio/command-line/adb
更新: 我最近了解到,在 18.0 及更高版本中,host.docker.internal 仅在 Docker for Mac 上受支持。
不好意思打扰了。但是我无法回答 this 问题所以我把它写在这里。
我正在使用 ubuntu:18.04 并尝试连接我的 Samsung Galaxy A3 2016 并使用 ADB 对其进行调试。设备未经授权,屏幕上没有弹出对话框!
我是如何解决问题的:
我很感兴趣问题是否仍然会在 Docker 容器中发生?答案是 "No!"。
在一个 Docker 容器中,我调用了以下内容:(这是本主题的答案:))
docker run --name android-adb -it -d --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu:16.04 bash
我下载了 platform-tools(使用 ADB 分发)。将其路径添加到环境中。并重新启动 bash
在 Docker 容器内重新启动 ADB 服务器并终止主机上的 ADB 服务器后。我发现智能手机屏幕上出现了确认对话框!
所以我认为在主机上问题出在 .android
目录中。只需将其移动到 .android-backup
。下一个 adb start-server
命令将创建一个新的。我还用最近的
platform-tools
文件夹
运行 只是 --privileged -v /dev/bus/usb:/dev/bus/usb
对我不起作用。
我尝试使用 -p 5037:5037
转发 adb 守护程序的监听端口,但这也没有帮助。
只有在我添加 --net host
后它才有效。
这意味着主机的网络接口暴露给 docker,所以如果你不介意的话就使用它。也许除了5037之外还有更多端口需要转发....
这对我有用。
- 将您的设备设置为 PPT 模式
- (可选)检查设备是否在本地可用
$ adb devices
I try with many options and only one works. Using
--network
flag as the next example
- 运行 容器
$ docker run -it --net host ubuntu bash
输出:
List of devices attached
464e128 device
我使用了 this Dockerfile。适用于 flutter 项目