Install gadb via go get
masterTo add gadb to your Go project, use the following command:
go get github.com/electricbubble/gadbrepository·master·Indexed 41 days ago
https://github.com/electricbubble/gadbA pure Golang implementation of an ADB (Android Debug Bridge) client. It allows developers to interact with Android devices from Go applications, providing functionality to list devices, execute shell commands via RunShellCommand, transfer files using Push and Pull, stream logs with Logcat, and manage TCP port forwarding.
To add gadb to your Go project, use the following command:
go get github.com/electricbubble/gadbThe shellTransport type manages communication over a network connection using a specific shell protocol. It allows sending typed messages (like shellStdout or shellStdin) and reading responses.
Messages are structured as:
shellMessageType).Note: shellTransport is an internal type used by the package to handle the transport layer for executing shell commands and reading their output.
// Note: shellTransport is unexported (starts with lowercase 's'),
// implying it is used internally by other exported components of gadb.
// Usage pattern involves interacting with the transport via Send and Read.
// Example of the protocol message types:
// shellStdin: 0
// shellStdout: 1
// shellStderr: 2
// shellExit: 3
// shellCloseStdin: 4The transport type provides low-level primitives for reading and writing ADB protocol data over a TCP connection. It handles command framing (prepending the 4-character hex length), response verification, and data unpacking.
Note: While the transport struct itself is unexported (lowercase), it is returned by internal factory functions (not shown in this file) or used as the basis for specialized transports like syncTransport and shellTransport via its methods.
The syncTransport type provides a mechanism for performing synchronous ADB operations, such as file transfers and directory entry reading, over a network connection (net.Conn). It handles the low-level protocol details including command framing, chunked data streaming, and status verification.
Note: syncTransport is an unexported type, typically instantiated via an internal constructor or provided through a higher-level API in the gadb package.
You can use gadb to interact with connected Android devices. The typical workflow involves:
gadb.NewClient().adbClient.DeviceList().dev.PushFile(file, remotePath).dev.RunShellCommand(command, args...) to perform actions like installing an APK via pm install.package main
import (
"github.com/electricbubble/gadb"
"log"
"os"
"strings"
)
func main() {
adbClient, err := gadb.NewClient()
checkErr(err, "fail to connect adb server")
devices, err := adbClient.DeviceList()
checkErr(err)
if len(devices) == 0 {
log.Fatalln("list of devices is empty")
}
dev := devices[0]
userHomeDir, _ := os.UserHomeDir()
apk, err := os.Open(userHomeDir + "/Desktop/xuexi_android_10002068.apk")
checkErr(err)
log.Println("starting to push apk")
remotePath := "/data/local/tmp/xuexi_android_10002068.apk"
err = dev.PushFile(apk, remotePath)
checkErr(err, "adb push")
log.Println("push completed")
log.Println("starting to install apk")
shellOutput, err := dev.RunShellCommand("pm install", remotePath)
checkErr(err, "pm install")
if !strings.Contains(shellOutput, "Success") {
log.Fatalln("fail to install: ", shellOutput)
}
log.Println("install completed")
}
func checkErr(err error, msg ...string) {
if err == nil {
return
}
var output string
if len(msg) != 0 {
output = msg[0] + " "
}
output += err.Error()
log.Fatalln(output)
}The List method retrieves directory information from a remote path on the device, returning a slice of DeviceFileInfo objects.
files, err := device.List("/sdcard/Documents")
if err != nil {
log.Fatal(err)
}
for _, f := range files {
fmt.Printf("Name: %s, Size: %d, IsDir: %v\n", f.Name, f.Size, f.IsDir())
}The Client provides several ways to retrieve information about connected devices:
DeviceSerialList(): Returns a slice of strings containing only the serial numbers of connected devices.DeviceList(): Returns a slice of Device objects. Each Device contains its serial number and a map of attributes (e.g., model, product) parsed from the ADB output.Note: Device objects are linked to the Client that discovered them.
// Get just the serials
serials, err := client.DeviceSerialList()
// Get full device objects with attributes
devices, err := client.DeviceList()
for _, dev := range devices {
fmt.Printf("Serial: %s, Attrs: %v\n", dev.Serial, dev.Attrs)
}After sending a command, use VerifyResponse() to check if the ADB server returned an OKAY status.
If the response is not OKAY, it attempts to unpack the error message using UnpackString() and returns a formatted error: command failed: <error_message>.
err := t.Send("sync:")
if err != nil {
return err
}
err = t.VerifyResponse()
if err != nil {
// command failed
}Use these methods to inspect or clear ADB port forwarding rules:
ForwardList(): Returns a slice of DeviceForward objects. Each object contains the Serial of the device, the Local address, and the Remote address.ForwardKillAll(): Removes all active port forwards on the ADB server.forwards, err := client.ForwardList()
for _, f := range forwards {
fmt.Printf("Device: %s, Local: %s, Remote: %s\n", f.Serial, f.Local, f.Remote)
}
// Clear all forwards
err := client.ForwardKillAll()The CreateSyncTransport() method transitions the current transport into a synchronous mode by sending the sync: command and verifying the OKAY response. It returns a syncTransport instance designed for the ADB sync protocol.
syncTp, err := t.CreateSyncTransport()
if err != nil {
// handle error
}
// Use syncTp for sync protocol operationsADB protocol often sends data preceded by a 4-character hex length. Use these methods to read and parse that data:
UnpackBytes(): Reads the 4-character hex length, converts it to an integer, and then reads that many bytes from the connection.UnpackString(): A wrapper around UnpackBytes() that returns the result as a string.// Unpack a string sent by the server
data, err := t.UnpackString()
if err != nil {
// handle error
}
fmt.Println("Received:", data)The CreateShellTransport() method returns a shellTransport instance, which is specialized for handling the ADB shell protocol.
shellTp, err := t.CreateShellTransport()
if err != nil {
// handle error
}
// Use shellTp for shell protocol operations