android shell命令获取结果

时间:2013-05-14 21:43:30

标签: android shell ping icmp

我处理的应用程序可以从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;

    }

}

2 个答案:

答案 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)

可能会吃掉输入的某些部分。我不明白它有什么好处。