我处理的应用程序可以从android shell发出ping或traceroute请求,我的应用程序读取结果并将其发布给用户。我的问题是我无法从命令中获取整个结果(消息)。例如,traceroute在显示HOPS之前显示初始消息,ping仅适用于1个数据包。否则(对于许多数据包)我得到ping请求的初始部分而不是结果。 我有一个root设备并安装了busybox以便拥有traceroute命令。
代码如下
package com.example.commandshelltest;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView tv1;
String out = new String();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String result=execute_reboot();
TextView tv1=(TextView)findViewById(R.id.textView1);
//tv1.setText(Integer.toString(result.length())); // i can see that while increasing the number of icmp packets in ping the length stays the same
tv1.setText(result);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
String execute_reboot()
{
Process process1;
try {
int BUFF_LEN =1024;
process1=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(process1.getOutputStream());
//os.writeBytes("traceroute 8.8.8.8\n");
os.writeBytes("ping -c 1 8.8.8.8\n");
os.flush();
InputStream stdout = process1.getInputStream();
byte[] buffer = new byte[BUFF_LEN];
int read;
while((read=stdout.read(buffer))>0)
while(true){
read = stdout.read(buffer);
out += new String(buffer, 0, read);
if(read<BUFF_LEN){
//we have read everything
break;
}
}
os.writeBytes("exit\n");
os.flush();
process1.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return out;
}
}
答案 0 :(得分:2)
对于每个遇到同样问题的人....我使用Run shell commands from android program中的示例作为代码 线程和休眠时间的使用解决了我的问题
public void runAsRoot(String[] cmds) throws Exception {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
InputStream is = p.getInputStream();
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
int readed = 0;
byte[] buff = new byte[4096];
boolean cmdRequiresAnOutput = true;
if (cmdRequiresAnOutput) {
while( is.available() <= 0) {
try { Thread.sleep(5000); } catch(Exception ex) {}
}
while( is.available() > 0) {
readed = is.read(buff);
if ( readed <= 0 ) break;
String seg = new String(buff,0,readed);
result=seg; //result is a string to show in textview
}
}
}
os.writeBytes("exit\n");
os.flush();
重要的部分是Thread.sleep(5000);
对于“ls”,睡眠时间并不重要。但是对于像ping或traceroute这样的命令,你需要时间,你必须等待结果,因此5000ms = 5秒足以获得ping HOP的响应。
答案 1 :(得分:0)
你不能确定这是真的:
if(read<BUFF_LEN){
//we have read everything
break;
实现可以在完全填充缓冲区之前返回,以避免等待太长时间。
另外一行
while((read=stdout.read(buffer))>0)
可能会吃掉输入的某些部分。我不明白它有什么好处。