从 Java 程序执行 ADB 命令

新手上路,请多包涵

我正在处理的程序使用 ADB(Android 调试桥)将文件发送到我的手机:

 for (String s : files)
    String cmd = "adb -s 0123456789ABCDEF push " + s + " /mnt/sdcard/" + s;
    try {
        InputStream is = Runtime.getRuntime().exec(cmd).getInputStream();
        while (is.read() != -1) {}
    } catch (IOException e) {
        e.printStackTrace();
    }

我希望程序等到 ADB 完成传输,但 ADB 作为守护进程运行,因此永远不会完成。但是程序会立即继续,并且文件不会以某种方式发送到我的手机(日志中没有例外)。当我从控制台运行命令时,它运行没有问题。

我究竟做错了什么?如何通过 ADB 正确发送文件?

注意: is.read() == -1 将不起作用,因为 ADB 守护进程将 所有输出 写入系统标准输出。我试过将它转发到一个文本文件中。它保持为空,输出仍然写入终端

编辑:读取 ADB 进程的错误流返回了每个 adb push 命令的 adb 帮助。再次: 确切的 命令(从 Eclipse 控制台复制)在终端中工作

编辑 2 :使用 ProcessBuilder 而不是 RUntime.getRuntime.exec() 导致以下错误:

 java.io.IOException: Cannot run program "adb -s 0123456789ABCDEF push "inputfile "outputfile""": error=2, File or directory not found

在 ProcessBuilder 的 start() 方法中使用 ADB 的绝对路径时也会发生同样的情况( /usr/bin/adb )。输入文件和输出文件字符串也是绝对路径,如 /home/sebastian/testfile 并且绝对存在。从终端运行命令时(打印字符串“cmd”,复制并粘贴),evreything 仍然可以正常工作。

原文由 s3lph 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

我终于让它工作了:

 ProcessBuilder pb = new ProcessBuilder("adb", "-s", "0123456789ABCDEF", "push", inputfile, outputfile);
Process pc = pb.start();
pc.waitFor();
System.out.println("Done");

我不知道什么问题 ProcessBuilder 字符串中有空格,但最后,它正在工作……

原文由 s3lph 发布,翻译遵循 CC BY-SA 3.0 许可协议

我用这种方式解决了:

 public class Utils {
    private static final String[] WIN_RUNTIME = { "cmd.exe", "/C" };
    private static final String[] OS_LINUX_RUNTIME = { "/bin/bash", "-l", "-c" };

    private Utils() {
    }

    private static <T> T[] concat(T[] first, T[] second) {
        T[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    public static List<String> runProcess(boolean isWin, String... command) {
        System.out.print("command to run: ");
        for (String s : command) {
            System.out.print(s);
        }
        System.out.print("\n");
        String[] allCommand = null;
        try {
            if (isWin) {
                allCommand = concat(WIN_RUNTIME, command);
            } else {
                allCommand = concat(OS_LINUX_RUNTIME, command);
            }
            ProcessBuilder pb = new ProcessBuilder(allCommand);
            pb.redirectErrorStream(true);
            Process p = pb.start();
            p.waitFor();
            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String _temp = null;
            List<String> line = new ArrayList<String>();
            while ((_temp = in.readLine()) != null) {
                System.out.println("temp line: " + _temp);
                line.add(_temp);
            }
            System.out.println("result after command: " + line);
            return line;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

如果您不需要 .bash_profile 中的环境变量,请删除“-l”参数。

我有一台 Mac,但它也应该可以在 Linux 上运行。

原文由 Sarpe 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题