1

Androidシェルからpingまたはtracerouteリクエストを作成できるアプリケーションで作業しており、アプリケーションは結果を読み取ってユーザーに投稿します。私の問題は、コマンドから全体の結果 (メッセージ) を取得できないことです。たとえば、traceroute は HOPS を表示する直前に最初のメッセージを表示し、ping は 1 つのパケットに対してのみ正しく機能します。それ以外の場合 (多くのパケットの場合)、結果ではなく、ping 要求の最初の部分を取得します。ルート化されたデバイスがあり、traceroute コマンドを使用するために busybox をインストールしました。

コードは次のとおりです

    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;

    }

}
4

2 に答える 2

2

同じ問題を抱えているすべての人のために.... Androidプログラムからシェルコマンドを実行するの例をコードとして使用しました 。スレッドとスリープ時間を使用すると、問題が解決しました

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 などのコマンドの場合は時間が必要で、結果を待つ必要があるため、ping HOP の応答を取得するには 5000ms=5 秒で十分です。

于 2013-05-15T11:22:53.783 に答える
0

これが真であると確信することはできません:

                 if(read<BUFF_LEN){
                     //we have read everything
                     break;

実装は、長すぎる待機を避けるために、バッファーが完全に満たされる前に戻る場合があります。

さらに、ライン

            while((read=stdout.read(buffer))>0)

入力の一部を消費する可能性があります。何がいいのかわかりません。

于 2013-05-14T21:58:06.533 に答える