2012-04-20 88 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); 
      } 
     } 
    }; 
}