How to run "adb commands" from UIAutomator

I previously used to inject shell commands in test setUp()/tearDown() using the runtime method, but it stopped working for me when I switched to UIAutomator 2.0 and Gradle.

If you're fine with using API 21 (lollipop) and above, Google provides this API for us:

InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("pm clear " + Constants.PACKAGE_NAME);

This method works for my use case. Source:

http://developer.android.com/reference/android/app/UiAutomation.html#executeShellCommand(java.lang.String)


Here is the code that works. I have copied the script file "command.sh" to external SDcard before running the UiAutomator test.

The code does not require any root permissions.

package ui;
import java.io.File;
import java.io.IOException;
import android.os.RemoteException;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;

public class SampleCode extends UiAutomatorTestCase {
    public void testHome() throws RemoteException,
        UiObjectNotFoundException {

    // press Home
    UiDevice mydevice = getUiDevice();
    if (!mydevice.isScreenOn()) {
        mydevice.wakeUp();
    }
    mydevice.pressHome();

    // Script path
    String filePath = "/mnt/sdcard_ext/command.sh";
    File command = new File(filePath);
    command.setExecutable(true);

    // Run command
    Process p = null;       
    try {
        Runtime.getRuntime().exec(
                "/system/bin/sh /mnt/sdcard_ext/command.sh");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (p != null)
            p.destroy();
    }

 }

}

Here is the content of "command.sh", output will be written to a file on the external SDcard

SDCARD="/mnt/sdcard_ext/"
LOG="$SDCARD/testlog.txt"
logcat -d >> $LOG 

Try this method-

public String shell(String cmd) {

    String s = null;
    try {
        Process p = Runtime.getRuntime().exec(cmd);

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(
                p.getInputStream()));

        BufferedReader stdError = new BufferedReader(new InputStreamReader(
                p.getErrorStream()));

        // read the output from the cmd
        String result = "";
        while ((s = stdInput.readLine()) != null) {
            result = result + s + "\n";
        }

        // read any errors from the attempted comd
        while ((s = stdError.readLine()) != null) {
            System.out.println(s);
        }
        return result;

    } catch (IOException e) {
        System.out.println("exception here's what I know: ");
        e.printStackTrace();
        return "Exception occurred";
    }
}  

Now you call-

String ls= Shell("ls");