用Go语言连接手机,这事儿比你想的简单

说实话,我一开始也以为用Go控制手机是个特别高大上的事儿,得用Java或者Kotlin写一堆底层代码,后来发现——不,Go就能干,而且干...

说实话,我一开始也以为用Go控制手机是个特别高大上的事儿,得用Java或者Kotlin写一堆底层代码,后来发现——不,Go就能干,而且干得还挺利索。

为什么是Go?不是Python不是Java?

你可能要问了:Python不是也能连手机吗?Java更是安卓的老本行,Go掺和什么?

其实我最早也是用Python写脚本连手机的,uiautomator2那套确实好用,但后来遇到一个问题——部署环境,客户那边是ARM的服务器,Python装依赖包装到想砸电脑,各种C扩展编译不过去,Go编译完一个二进制文件丢上去就跑,干净利落。

另外还有一个点,Go的并发模型特别适合处理手机连接这种场景,你要同时监控多台手机的状态,接收日志,发指令——Go的goroutine简直就像为这个量身定做的。

怎么连?三个主流方案

我折腾了大半个月,把市面上主流的Go连接手机方案都试了一遍,下面这张表你可以收藏,选方案的时候对照着看:

方案 原理 适用场景 学习成本
ADB + exec.Command 调用系统adb命令 快速原型、自动化测试
gadb 纯Go实现的ADB协议 生产环境、跨平台部署
scrcpy-go 屏幕镜像+控制 远程协助、投屏 中高

ADB命令包装(最省事)

这个方案其实没什么高深的,就是Go调用系统的adb命令。

package main
import (
    "fmt"
    "os/exec"
    "strings"
)
func main() {
    // 获取连接的设备列表
    cmd := exec.Command("adb", "devices")
    out, _ := cmd.Output()
    lines := strings.Split(string(out), "\n")
    for _, line := range lines {
        if strings.Contains(line, "\tdevice") {
            deviceID := strings.Split(line, "\t")[0]
            fmt.Printf("发现设备:%s\n", deviceID)
        }
    }
}

你看,就这么几行代码,手机就连上了,我当年第一次跑通这个的时候,站在工位上喊了一句“卧槽,成了”,结果被隔壁组的同事白了一眼。

但这个方案有个隐患——你得保证运行环境里有adb,Docker环境下经常没有,这时候就得用方案二了。

gadb库(纯Go实现)

gadb这个库挺有意思,它把adb协议用Go重写了一遍,什么意思呢?就是你不需要系统装adb,Go代码自己就能和手机通信

package main
import (
    "fmt"
    "log"
    "github.com/electricbubble/gadb"
)
func main() {
    client := gadb.NewClient()
    devices, _ := client.ListDevices()
    for _, device := range devices {
        fmt.Printf("设备型号:%s\n", device.Model())
        // 获取设备信息
        properties, _ := device.GetProperties()
        for key, value := range properties {
            if key == "ro.build.version.sdk" {
                fmt.Printf("安卓SDK版本:%s\n", value)
            }
        }
        // 安装APK
        err := device.Install("app-release.apk")
        if err != nil {
            log.Printf("安装失败:%v", err)
        }
    }
}

当时我拿着这个去给客户演示,客户问“你这个依赖什么环境”,我直接把二进制文件丢给他,说“双击运行就行”,那感觉,爽。

注意:用gadb之前,手机还是得开USB调试或无线调试,这个逃不掉。

scrcpy-go(屏幕控制)

如果你需要看到手机屏幕甚至远程操作,那就得上scrcpy了,Go这边有移植版本,虽然功能没有原版scrcpy那么全,但基本够用。

这个方案稍微复杂一点,涉及到视频流解码,我这里就不贴完整代码了——不然这篇文章得变成技术手册,核心就是:启动服务端,接收H264流,再推送到界面。

连不上?这五个坑我全踩过

说真的,我一开始连手机踩的坑比我写的代码还多。

驱动问题(Windows用户注意)

Windows上不装驱动连个鬼啊,我当时插上手机,adb devices出来一个空的列表,还以为代码写错了,查了半天发现是驱动没装,解决办法:去手机厂商官网下载USB驱动,或者用“驱动人生”这种工具自动装。

无线调试连不上

安卓11开始有无线调试功能,但必须是同一局域网,而且第一次连接还得用USB线配个对:

adb pair 192.168.1.100:41387
# 输入配对码
adb connect 192.168.1.100:16378

配对完才能无线连,我第一次不知道还要pair这一步,在路由器前坐了俩小时。

Go版本要求

gadb库要求Go 1.18以上,因为用到了泛型,你要是还在用老的1.16,赶紧升级吧,不然后面很多新库都用不了。

权限弹窗处理

当你用代码操作手机时,会频繁弹出“是否允许USB调试”“是否允许安装未知来源应用”这种弹窗,必须在手机上提前勾选“一律允许”,不然流程跑一半就卡住了。

多设备冲突

用Go语言连接手机,这事儿比你想的简单

同时接两台手机,adb会有冲突,解决办法是在命令里指定设备:

cmd := exec.Command("adb", "-s", deviceID, "shell", "input", "tap", "500", "1000")

一个完整的例子:批量截图工具

说了这么多,来点实际的,我们写个工具,给连接的所有手机截图,并保存到本地。

package main
import (
    "fmt"
    "os"
    "os/exec"
    "path/filepath"
    "time"
)
func screenshotDevice(deviceID, saveDir string) {
    // 截图
    cmd := exec.Command("adb", "-s", deviceID, "shell", "screencap", "-p", "/sdcard/screen.png")
    cmd.Run()
    // 拉到本地  
    localPath := filepath.Join(saveDir, fmt.Sprintf("%s_%d.png", deviceID, time.Now().Unix()))
    pullCmd := exec.Command("adb", "-s", deviceID, "pull", "/sdcard/screen.png", localPath)
    pullCmd.Run()
    fmt.Printf("✅ 设备 %s 截图已保存:%s\n", deviceID, localPath)
}
func main() {
    // 取所有设备
    out, _ := exec.Command("adb", "devices").Output()
    devices := parseDevices(string(out))
    if len(devices) == 0 {
        fmt.Println("⚠️ 没发现任何设备,请检查连接")
        return
    }
    saveDir := "screenshots"
    os.MkdirAll(saveDir, 0755)
    for _, device := range devices {
        screenshotDevice(device, saveDir)
    }
}

这个代码我跑了好多次,效果还不错。唯一的问题是,手机会有截图音效,如果同时连了10台手机,办公室里就会此起彼伏地响,你想象一下那个画面。

说点大实话

用Go连接手机,技术本身不难,难的是处理好各种边界情况——连不上怎么办?权限拒绝怎么办?adb服务挂了怎么办?

我建议你从方案一开始,先跑通一条最简单的命令,看到手机给你响应,那种“我的代码指挥了另一个设备”的爽感,会支撑你继续搞下去的。

而且说实话,用Go写这种工具类东西,真的会上瘾,编译快、部署简单、系统兼容性好,我现在连自己电脑上的一些小脚本都想用Go重写一遍。

至于复杂的GUI操作,还是交给Appium或者Airtest吧——Go没那么全能,但做一个连接手机的中间层,绰绰有余。

本文来自作者[kyadmin]投稿,不代表思利达立场,如若转载,请注明出处:http://kj.c-lida.com/post/18.html

(14)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-06-09

    我是思利达的签约作者“kyadmin”!

  • kyadmin
    kyadmin 2026-06-09

    希望本篇文章《用Go语言连接手机,这事儿比你想的简单》能对你有所帮助!

  • kyadmin
    kyadmin 2026-06-09

    本站[思利达]内容主要涵盖:郑州思利达智能科技有限公司

  • kyadmin
    kyadmin 2026-06-09

    本文概览:说实话,我一开始也以为用Go控制手机是个特别高大上的事儿,得用Java或者Kotlin写一堆底层代码,后来发现——不,Go就能干,而且干...

    联系我们

    工作时间:周一至周五,9:30-18:30,节假日休息

    关注我们