簡體   English   中英

從 Java 程序執行 ADB 命令

[英]Execute ADB command from Java program

我正在開發的程序使用 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 進程的 ErrorStream 返回了每個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 ) 時也會發生同樣的情況。 inputfile 和 outputfile 字符串也是絕對路徑,如/home/sebastian/testfile並且肯定存在。 從終端運行命令(打印字符串“cmd”,復制和粘貼)時,evreything 仍然可以正常工作。

我終於讓它工作了:

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

我不知道ProcessBuilder對字符串中的空格有什么問題,但最后,它正在工作......

我是這樣解決的:

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 中不需要 env 變量,請剪切“-l”參數。

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

 public static void adbpush() {
        System.out.println("adb push....");
        String[] aCommand = new String[] { adbPath, "push", inputFile(String),OutputDirectory };
        try {
            // Process process = new ProcessBuilder(aCommand).start();
            Process process = Runtime.getRuntime().exec(aCommand);
            process.waitFor(3, TimeUnit.SECONDS);
            System.out.println("file pushed");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

最好給出 ADB 執行的完整路徑:像這樣$ANDROID_HOME/platform-tools/adb devices

這是您可以使用的完整代碼:

String cmd = "$ANDROID_HOME/platform-tools/adb devices";
ProcessBuilder processBuilder = new ProcessBuilder();
if (Config.osName.contains("Windows"))
    processBuilder.command("cmd.exe", "/c", cmd);
else
    processBuilder.command("bash", "-c", cmd);

Process process = processBuilder.start();
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
string cmd = "/system/bin/input keyevent 23\n";
os.writeBytes(cmd);

手機必須root。 在這里我執行了 adb 命令“input keyevent 23”。 請記住,當您通過 su 執行 adb 命令時,您不需要添加“adb shell input keyevent 23”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM