'Run adb on the device itself, i.e. as if it were the PC issuing the commands

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();


Solution 1:[1]

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+.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1