2012-04-20 110 views
4

在我的應用程序中,我需要掃描本地子網(192.168.1。*)以收集所有連接設備的MAC地址列表。Android子網掃描

我目前使用以下策略:

  1. 開始的同時,255平在每個返回的過程中Runtime.exec("ping -c 1 <addr>")
  2. 使用waitFor()命令收集退出代碼
  3. 關閉輸入流的處理和銷燬他們
  4. 閱讀/proc/net/arp文件並解析MAC地址

在大多數情況下,這個工作非常好,並提供了一個快速掃描。但是在某些設備上(比如android 1.5,有時候> 4.0),執行會在創建進程時被阻塞(在幾個設備啓動成功後),並且無法殺死正在運行的線程。

你看到什麼我可以嘗試解決這個問題?或者其他任何不會花太長時間的策略?

回答

7

這可以通過使用運行INetAddress.isReachable()方法的線程池(而不是在本機進程中運行ping命令)來解決。

private static final int NB_THREADS = 10; 

public void doScan() { 
    Log.i(LOG_TAG, "Start scanning"); 

    ExecutorService executor = Executors.newFixedThreadPool(NB_THREADS); 
    for(int dest=0; dest<255; dest++) { 
     String host = "192.168.1." + dest; 
     executor.execute(pingRunnable(host)); 
    } 

    Log.i(LOG_TAG, "Waiting for executor to terminate..."); 
    executor.shutdown(); 
    try { executor.awaitTermination(60*1000, TimeUnit.MILLISECONDS); } catch (InterruptedException ignored) { } 

    Log.i(LOG_TAG, "Scan finished"); 
} 

private Runnable pingRunnable(final String host) { 
    return new Runnable() { 
     public void run() { 
      Log.d(LOG_TAG, "Pinging " + host + "..."); 
      try { 
       InetAddress inet = InetAddress.getByName(host); 
       boolean reachable = inet.isReachable(1000); 
       Log.d(LOG_TAG, "=> Result: " + (reachable ? "reachable" : "not reachable")); 
      } catch (UnknownHostException e) { 
       Log.e(LOG_TAG, "Not found", e); 
      } catch (IOException e) { 
       Log.e(LOG_TAG, "IO Error", e); 
      } 
     } 
    }; 
}