2

我正在开发一个程序,该程序需要能够确定 Xlocation 的 android 设备上的内容。我正在使用“su ls Xlocation”

我想取回文件的数组列表,但只能设法取回第一个项目。我是否缺少获取下一行的命令?或者还有什么我需要做的。

下面是我发送的命令

String[] commands = new String[]{"ls /system/app/"};
return doCommand(commands);

下面是我当前的 doCommand 方法

    private boolean doCommand(String[] commands)
    {
    ArrayList<String> output = new ArrayList<String>();

    boolean ran = false;
    try
    {
        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        DataInputStream ins = new DataInputStream(process.getInputStream());

        // This part works I sends the command right!
        for (String single : commands) 
        {
            os.writeBytes(single + "\n");
            os.flush();
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
            ran = true;
        }

        int av = -1;
        while (av != 0)
        {

//////////////////////////// WORKING ON THIS TO GET ALL INFO /////////////////
            av = ins.available();
            if (av != 0) 
            {
                byte[] b = new byte[av];
                ins.read(b);
                output.add(new String(b));
                System.out.println(new String(b) + "Recieved form modem");
            }
        }
    }
    catch(Exception ex){}
    return ran;
}

如目前所见,它只返回真或假。但是在调试中运行我只得到输出中的第一项。(输出=“[first.apk”)

编辑了较新的版本;

    public ArrayList<String> doCommand(String[] commands)
{

    ArrayList<String> output = new ArrayList<String>();

    try
    {

        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());  
        DataInputStream ins = new DataInputStream(process.getInputStream());
        for (String single : commands) 
        {
            os.writeBytes(single + "\n");

            //os.flush();
            output.add("true");
        }
        os.writeBytes("exit\n");


        byte[] bc = new byte[10000];
        String st = "";
        while(ins.read(bc) != -1)
        {
        st += new String(bc);
        os.flush();

        }
        output.add(st);


        os.flush();
        os.close();
        ins.close();
        process.waitFor();          
    }
    catch(Exception ex)
    {}

    return output;
}

现在获得了相当数量的输出,但仍然不是所有目录都在我检查过的字节 [10000] 大小限制内有大项目的地方。

如果有人想对此进行改进并获得有效的确切答案,那么我仍然会查看此帖子。

谢谢

4

2 回答 2

2

您可以尝试从我的开源用户管理 ( GitHub ) 应用程序中调整此方法来执行您想要的操作。这将在终端命令之后读取输出的每一行:

public static String[] getUserList()
{
    Process p;
    try {
        p = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(p.getOutputStream());  
        BufferedReader bf = new BufferedReader(new InputStreamReader(p.getInputStream()));

            os.writeBytes("pm list-users"+"\n");
            os.writeBytes("exit\n"); 
            ArrayList<String> users = new ArrayList<String>();
            String test;
            bf.readLine();
            while((test = bf.readLine()) != null)
            {
                users.add(test);
            }

            String[] userList = (String[]) users.toArray(new String[users.size()]);



        os.flush();
        return userList;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
于 2013-01-10T20:53:59.910 回答
2

我对 Java 有点陌生,但我相信这个问题只是一个小小的疏忽。我在其中遇到过几次 Python ;)

因为您已将以下内容添加到您的 while 循环中:

        os.writeBytes("exit\n");
        os.flush();

每次迭代后,您都试图退出终端会话。在第一次迭代之后,终端会话已经关闭,所以这可以解释为什么只返回第一个结果。

我建议在 while 循环完成后添加退出代码,以确保您不会将其余命令发送到死会话。或者,您也可以在每次迭代期间重新创建 os ,但这似乎有点多余。;)

编辑#1

我不熟悉字节的使用,但我已经能够使用类似的 while 循环来解析命令的输出。我还在输入中添加了 stderr 以确保在需要时清空缓冲区。乍一看您的新代码,您似乎在 while 循环的每次迭代期间定义了一个新字符串,而不是将该行附加到变量中。这将导致您的变量在每次迭代期间被覆盖。;)

下面是我过去用来完成类似任务的一些代码。我很快从我的源代码进行了修改,但我目前无法对其进行测试。请记住,您的os 是我的stdout,而您的ins是我的stdin

Runtime          terminal = (Runtime) Runtime.getRuntime();
Process          process  = terminal.exec("su");
DataOutputStream stdout   = new DataOutputStream(process.getOutputStream());
InputStream      stderr   = process.getErrorStream();
BufferedReader   stdin    = new BufferedReader(new InputStreamReader(stderr));
String           line     = "";
String           output   = "";

// Execute command and flush 
stdout.writeBytes("your command here\n");
stdout.flush();

// Append stdin.readLine() to output variable until line is null
while ((line = stdin.readLine()) != null)
    output += line;

// I've had mixed luck getting waitFor() to work, but technically it should force
// the shell to wait until the command completes. Uncomment it to try it out.
//process.waitFor();
stdout.writeBytes("exit\n");
stdout.flush();

// Print output to logcat
System.out.println(output);
于 2014-05-10T04:05:00.470 回答