簡體   English   中英

Java ADB Shell不返回任何內容

[英]Java ADB shell returns nothing

我想編寫一個Java程序來查找設備並列出其內容。 為此,我首先通過Java的Process類觸發“ adb設備”並解析輸出,該輸出只是finde。 然后我要觸發此命令:

adb shell -s DEVICE-SERIAL /sdcard/

當我將其放入終端時,會得到正確的輸出,即/ sdcard /根目錄中所有文件夾和文件的列表。

當我將其放入Java代碼時,不會返回任何內容。 但是,Stderr包含拼寫adb命令時獲得的標准幫助頁面。 這是有趣的事情:為了調試,我輸出了每個發送到ADB的命令。 如果我運行程序並復制完全相同的生成命令,然后在終端中運行它,則工作正常。

這是為什么? 供參考,這是我的代碼摘錄:

ADB.java:

public static String runShellCommand(Device d, String command) {
    return runCommand(d, "shell " + command);
}

public static String runCommand(Device d, String command) {
    Runtime runtime = Runtime.getRuntime();
    String full = "";
    String error = "";

    try {
        if (d != null) {
            command = "-s " + d.getSerial() + " " + command;
        }

        System.out.println("Running command: adb " + command);
        Process process = runtime.exec(new String[] {ADB_LOCATION, command});

            process.waitFor();

        BufferedReader stdin = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader errin = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        String line;

        while ((line = stdin.readLine()) != null) {
            full += line;
        }

        while ((line = errin.readLine()) != null) {
            error += line;
        }

        if (!error.isEmpty()) {
            System.err.println("\n=== ADB reports: ===");
            System.err.println(error);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        System.out.println("App was overenthuasiastic. Couldn't wait for thread to finish.");
    }

    return full;
}

Device.java:

public ArrayList<Folder> getFoldersInDirectory(String dir) {
    String[] list = ls(dir);

    for (String s: list) {
        System.out.println(s);
        System.out.println(isFolderOrFile(dir + s));
    }

    // Just for debugging, gets completed once this runs.
    return null;
}

protected String[] ls(String dir) {
    String result = ADB.runShellCommand(this, "ls " + dir);
    System.out.println(result);

    return result.split("\n");
}

正如我之前所說,其他所有命令都可以正常運行(我測試了設備,get-state,get-serialno)。

輸出: 輸出

runtime.exec()的參數錯誤。 當您應該使用{'adb', '-s', 'xxxx', 'shell', 'ls /sdcard/'}{'adb', '-s xxxx shell "ls /sdcard/"'}您正在使用{'adb', '-s xxxx shell "ls /sdcard/"'} {'adb', '-s', 'xxxx', 'shell', 'ls /sdcard/'}

對於OP來說可能為時已晚,但對以后的觀看者可能有用。

最近,我不得不集成一個系統以通過adb與實際設備緊密協作。 花了一些時間來弄清楚如何“適當地”做所有令人討厭的事情。 然后我想到了一個創建至少處理一些基本adb命令(adb設備,shell,pull,push,install)的庫的想法。 它可以使用相同的API在本地計算機上或通過ssh(具有密鑰交換設置)在遠程計算機上執行adb。 不要與adb shell轉發混淆;)。

它在Apache 2.0許可下: https : //github.com/lesavsoftware/rem-adb-exec

感謝AlexP。我找到了一個可行的解決方案(盡管需要解析輸出,但這是另一回事了):

我剛剛修改了runCommand(),將參數放入字符串數組中,然后將其提供給exec:

public static String runCommand(Device d, String command) {
        Runtime runtime = Runtime.getRuntime();
        String full = "";
        String error = "";

        try {
            String[] cmdWithDevice = new String[5];
            String[] cmdWithoutDevice = new String[2];

            if (d != null) {
                cmdWithDevice[0] = ADB_LOCATION;
                cmdWithDevice[1] = "-s";
                cmdWithDevice[2] = d.getSerial();
                cmdWithDevice[3] = "shell";
                cmdWithDevice[4] = command;

                command = "-s " + d.getSerial() + " " + command;
            } else {
                cmdWithoutDevice[0] = ADB_LOCATION;
                cmdWithoutDevice[1] = command;
            }

            System.out.println("Running command: adb " + command);
            // Process process = runtime.exec(new String[] {ADB_LOCATION, command});
            Process process = runtime.exec(cmdWithDevice[0] == null ? cmdWithoutDevice : cmdWithDevice);

            BufferedReader stdin = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedReader errin = new BufferedReader(new InputStreamReader(process.getErrorStream()));

            process.waitFor();

            String line;

            while ((line = stdin.readLine()) != null) {
                full += line;
            }

            while ((line = errin.readLine()) != null) {
                error += line;
            }

            if (!error.isEmpty()) {
                System.err.println("\n=== ADB reports: ===");
                System.err.println(error);
            }

            stdin.close();
            errin.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            System.out.println("App was overenthuasiastic. Couldn't wait for thread to finish.");
        }

        return full;
    }

由於某些原因,如果我僅以編程方式手動輸入傳入的參數來運行runtime.exec,它將無法正常工作。

盡管該解決方案有點笨拙,但需要適當的實現。 此外,該解決方案還假定每個特定於設備的命令都是針對Shell的。

暫無
暫無

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

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