2012-01-30 48 views
5

ホスト(標準AndroidまたはNDK実装)にpingを実行し、応答の詳細情報を入手する方法はありますか? (時間、TTL、パッケージを失った、など。)私は、この機能を持っていますが、任意のを見つけることができないいくつかのオープンソースアプリを考えていた ...Android ICMP ping

おかげ

答えて

13

私の知る限りでは、ICMP ECHOを送信する必要性を要求しますルート(つまり、設定する必要があるアプリ) - は現在「在庫あり」のAndroid(地獄では、InetAddress#isReachable()でもAndroidではjokeで動作しません)。

非常に基本的な例では/ usr/binに/のpingを使用して&プロセス - AsyncTaskを使用して、pingの結果を読み出す:

public class PingActivity extends Activity { 
    PingTask mTask; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     mTask = new PingTask(); 
     // Ping the host "android.com" 
     mTask.execute("android.com"); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mTask.stop(); 
    } 

    class PingTask extends AsyncTask<String, Void, Void> { 
     PipedOutputStream mPOut; 
     PipedInputStream mPIn; 
     LineNumberReader mReader; 
     Process mProcess; 
     TextView mText = (TextView) findViewById(R.id.text); 
     @Override 
     protected void onPreExecute() { 
      mPOut = new PipedOutputStream(); 
      try { 
       mPIn = new PipedInputStream(mPOut); 
       mReader = new LineNumberReader(new InputStreamReader(mPIn)); 
      } catch (IOException e) { 
       cancel(true); 
      } 

     } 

     public void stop() { 
      Process p = mProcess; 
      if (p != null) { 
       p.destroy(); 
      } 
      cancel(true); 
     } 

     @Override 
     protected Void doInBackground(String... params) { 
      try { 
       mProcess = new ProcessBuilder() 
        .command("/system/bin/ping", params[0]) 
        .redirectErrorStream(true) 
        .start(); 

       try { 
        InputStream in = mProcess.getInputStream(); 
        OutputStream out = mProcess.getOutputStream(); 
        byte[] buffer = new byte[1024]; 
        int count; 

        // in -> buffer -> mPOut -> mReader -> 1 line of ping information to parse 
        while ((count = in.read(buffer)) != -1) { 
         mPOut.write(buffer, 0, count); 
         publishProgress(); 
        } 
        out.close(); 
        in.close(); 
        mPOut.close(); 
        mPIn.close(); 
       } finally { 
        mProcess.destroy(); 
        mProcess = null; 
       } 
      } catch (IOException e) { 
      } 
      return null; 
     } 
     @Override 
     protected void onProgressUpdate(Void... values) { 
      try { 
       // Is a line ready to read from the "ping" command? 
       while (mReader.ready()) { 
        // This just displays the output, you should typically parse it I guess. 
        mText.setText(mReader.readLine()); 
       } 
      } catch (IOException t) { 
      } 
     } 
    } 
} 
+0

nope。私は電話をしていない、ネットPingのアプリは設計どおりに動作しています。 –

+1

それはおそらく、[java.lang.Process](http://developer.android.com/reference/java/lang/Process.html)を使用してpingコマンドを実行しています - そのコマンドはsetuidであり、出力を解析する - Javaから直接実行することはできません(プロセスの例では実際にpingコマンドが実行されています)。 – Jens

+0

'ping 'コマンドをroot権限のないjava.lang.Processで実行できますか? –

0

私はルートなしでpingコマンドを実行するための方法を発見しました。
最初の「SH」プロセスを生成し、そのシェルで「ピング」を実行し、コード:

p = new ProcessBuilder("sh").redirectErrorStream(true).start(); 

DataOutputStream os = new DataOutputStream(p.getOutputStream()); 
os.writeBytes("ping -c 10 " + host + '\n'); 
os.flush(); 

// Close the terminal 
os.writeBytes("exit\n"); 
os.flush(); 

// read ping replys 
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
String line; 

while ((line = reader.readLine()) != null) { 
    System.out.println(line); 
} 

それはCyanogenMod 7.1.0(アンドロイド2.3.7)と私のHTCデバイス上で正常に動作します

+1

なし-w <# seconds>をpingコマンドで実行すると、私はハングアップする可能性があります。これを試している人には警告です。 –

+1

-1シェルを作成してからpingを起動するのは難しい設計です。それはより多くの構文解析と入力の難しさを伴います。 pingを直接起動する方が良いです。 –

関連する問題