如何在运行时使用"su"发送命令并从DataInputStream获取所有行



我正在开发一个程序,需要能够确定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("exitn");
            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;
}

目前只返回true或false。然而,在调试中运行,我只得到输出中的第一项。(output = "[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("exitn");

        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]的大小限制内,我检查了

如果有人想改进这一点,并得到一个确切的答案,这样做,我仍然检查这个帖子。

谢谢

你可以尝试从我的开源用户管理(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("exitn"); 
            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;
    }
}

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

因为你在while循环中添加了下面的代码:

        os.writeBytes("exitn");
        os.flush();

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

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

编辑# 1

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

下面是我过去用来完成类似任务的一些代码。我很快从我的源代码修改,但我目前无法给它一个测试运行。记住你的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 heren");
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("exitn");
stdout.flush();
// Print output to logcat
System.out.println(output);

相关内容

  • 没有找到相关文章

最新更新