How can I deploy and execute an application on a device connected to a remote system?

adb, android, android-testing

Solution

From the `adb` tag wiki:

Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with an emulator instance or connected Android-powered device. It is a client-server program that includes three components:

- A client, which runs on your development machine. You can invoke a client from a shell by issuing an adb command. Other Android tools such as the ADT plugin and DDMS also create adb clients.

- A server, which runs as a background process on your development machine. The server manages communication between the client and the adb daemon running on an emulator or device.

- A daemon, which runs as a background process on each emulator or device instance.

`adb connect` command is used to connect the local `adb` server with the `adbd` daemon on a network connected device. But what you want is to connect the local `adb` client to the remote (running on another system) `adb` server. The default behavior of the `adb` executable is to connect to the local instance of the `adb` server. If none found it would try to start one. This approach works great for most environments where all development is being done on a single system. But in more complicated environments it may result in multiple instances of `adb` server being launched. And because `adbd` daemon only supports being connected to a single `adb` server at a time - the device will get recognized by one system and will appear missing everywhere else.

So in order for `adb` to reliably recognize devices in those more complicated configurations you need to tell `adb` to stop guessing and manually specify which part of `adb` (i.e. server or client) should be running on which system.

First off make sure that you have the same and sufficiently recent version of `adb` (the latest Google official version usually works the best) installed on both local and remote systems. And that no `adb` servers are currently running on either system.

Then start an instance of the `adb server` on the remote system (the one which you will be plugging the devices into) with this command:

adb -a -P <PORT_NUMBER> nodaemon server

Now you can force `adb` client on the local system to use the other (remote) server instead of starting its own (local) instance by adding `-H <REMOTE_IP> -P <PORT_NUMBER>` to your `adb` commands:

adb -H <REMOTE_IP> -P <PORT_NUMBER> devices

Alternatively, setting `ANDROID_ADB_SERVER_ADDRESS=<REMOTE_IP>` and `ANDROID_ADB_SERVER_PORT=<PORT_NUMBER>` environment variables on the client side would allow you to avoid having to specify the `<REMOTE_IP>` and `<PORT_NUMBER>` for every `adb` command.

And if omitted the `<PORT_NUMBER>` would default to `5037`.

This official built-in solution for `adb` orchestration is not a mutually exclusive alternative to the SSH tunneling - it just addresses another more important issue. You can add tunneling on top of this to add extra security or help with routing issues in a multi site network environment. But the tunneling alone will not be able to solve all the `adb` connectivity problems.

Same goes for the virtualized environments - running multiple `adb server` instances between host and guest systems will also result in the `adb` connectivity issues.

Problem

I have a requirement to deploy a test application and issue commands on a device connected to another machine in the same network. I read through http://developer.android.com/tools/help/adb.html#directingcommands but I am not able to find the answer. I tried using `adb connect <remote machine IP>` but I got `unable to connect` error. Is there a way to deploy applications and execute `adb` commands on a device connected to a remote system?

Original source