11

My goal is to write an app which runs on a handset and lets the user choose from a list of APK's, then installs the one selected to an Android Things device on the same network.

We can actually forget Android Things because the same code would work between two handsets, it's just that there it would be pointless because the target can just receive the APK in many other ways such as an attachment, BT etc. AT devices only have ADB for this, apart from the recently announced Android Things Console which is overkill for regular local development. I'm therefore looking to replicate the sequence a PC would go through to install it, i.e. "adb connect, adb install ..." etc but from the handset itself. We can assume all devices involved are rooted.

It seems to me this means my app has to issue these commands as a process, but I'm having a hard time getting it fully working. When I issue "adb help" I get back the help message, and when I issue "adb reboot" the device reboots, so I think I'm on the right lines. It's when I try anything apart from those I get nothing back - the example of "adb shell ping -c 1 192.168.62.40" fails, but is OK from ADB on the PC. Also, it's very curious "adb version" fails which again is OK from the terminal.

At first I thought the handsets might only have an "adb lite" installed which has just enough to get them to work as an adb target, but using a shell from a PC showed that's not the case.

Here's the code I'm trying:

Process process = Runtime.getRuntime().exec("su adb help");
//Process process = Runtime.getRuntime().exec("su adb reboot");
//Process process = Runtime.getRuntime().exec("su adb version");   
//Process process = Runtime.getRuntime().exec("su adb shell ping -c 1 192.168.62.40");
process.waitFor();

Log.d("PROCESS", "Status: "+process.exitValue());
BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader(process.getInputStream()));

StringBuilder everything = new StringBuilder();
String line;
while( (line = bufferedReader.readLine()) != null) {
    everything.append(line);
}

Log.d("PROCESS", "Process output: "+everything.toString());

Toast.makeText(MainActivity.this, everything.toString(), Toast.LENGTH_SHORT).show();

2 Answers 2

10

The problem is that the adb client (which you use to communicate to the ADB server which communicates to and from a device on a development machine) is not packaged on an Android device. The adbd daemon, however, (used to communicate between the adb client and the device) can and will be found on an Android system.

There are a few options to help use the adb client on an Android device:

  • Try and build the adb client for an Android device from the adb sources on GitHub.
  • Try and make a makeshift adb "client". Since the adb client and adbd daemon communicate via USB or TCP, you could try emulating the communication protocols to open read/write streams on the device. More on the client-daemon communication protocols here. This library that I am working on might help you: eviltak/adb-nmap

The quick and dirty option is to build the adb client from sources and push to the device. That is, if you can get it to build on an Android device.

The second option is probably the most time consuming, but can be the most "clean" choice. You will, however, have to emulate the adb authentication system, properly handle streams and so on, which can be cumbersome. The source will help you.

In either case, the GitHub adb source directory should have everything you need for the long road ahead.

3
  • Hey thanks very much. TBH I was pulling my hair out thinking I'd been invoking the process wrong, but now you've explained it I can see why there was a lot more to it than I first assumed. It would still be useful for AT, but my workload right now means I'll have to raincheck it for the moment. Commented Jul 2, 2017 at 17:03
  • Actually thought of another way which might prove easier ... use a server. You could use the control handset to select, upload and then install the APK's, but all you're really doing is telling the server, which would have adb installed, to issue the appropriate commands to the target. Commented Jul 3, 2017 at 7:38
  • @CarlWhalley I thought of suggesting that, but that requires a machine running adb on the network. You will still have to do some work though. At the potential loss of security you could set up a "passthrough" socket for the adb server as it uses a loopback socket to enable communication to and from the CLI client. I plan on doing something similar albeit more restrictive for an app which uses my adb-nmap library to connect to machines with the adb server (and the passthrough socket) up and running on the network.
    – EvilTak
    Commented Jul 4, 2017 at 10:05
6

Four years later...

I was looking for the same situation.

Adb requires a network connection as it is a client-server connection where the Android device is the server and the computer the client.

To work around this, you need Termux (an Android terminal with package manager) and a local VPN such as Netguard. Root access is not required.

In Termux you can install a native Android version of adb which is step 1 by apt install android-tools. But adb should make a network connection to the device itself. Then a VPN can be useful. VPNs operate locally, where the device acts as a VPN server such as for adblocking like Netguard. Then your device gets another network with another IP address, e.g. Netguard makes 10.1.10.1 which I use as an example (your VPN might issue a different address). Run adb connect 10.1.10.1 The device might prompt (only once) with 'allow connections from computer ..blabla...' and consent this. Then run adb connect 10.1.10.1:5555 and you are connected. Now adb commands can be run from the Termux command shell regardless on the device itself or via an SSH connection.

Note: Plugging in USB is still needed after reboot, unless you have Android 11+.

1
  • thank you for this. I thought could make The android is server and the computer is client Commented Aug 21, 2022 at 1:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.