我正在开发一个程序,需要能够确定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;
}
如目前所见,它只返回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("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]我检查过。
如果有人想要对此进行改进并获得有效的确切答案,我仍然会查看此帖子。
由于
答案 0 :(得分: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;
}
}
答案 1 :(得分:2)
我对Java有点新意,但我认为这个问题只是一个小小的疏忽......我用Python遇到过几次;)
因为您已将以下内容添加到while循环中:
os.writeBytes("exit\n");
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 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);