简体   繁体   English

如何在Android上获取本地网络中所有设备的IP地址和名称

[英]How to get IP address and names of all devices in local network on Android

I want to see all the connected devices on my network with java, but I can't get it working. 我想用java看到我网络上的所有连接设备,但是我无法让它工作。 I have attached some screenshots below of how I want it to be output. 我在下面附上了一些截图,说明我希望如何输出。 I would like to have the name (for example "TP Link Router" or "Nexus 5X") and the IP address. 我想要名称(例如“TP Link Router”或“Nexus 5X”)和IP地址。

I have searched a lot on google and stackoverflow, but nothing seemed to work for me. 我在谷歌和stackoverflow上搜索了很多,但似乎没有什么对我有用。 Even GitHub has no effective code. 即使是GitHub也没有有效的代码。 I tried searching for UPnP, Local Area Network, subnets, etc, but found nothing. 我尝试搜索UPnP,局域网,子网等,但一无所获。

InetAddress localhost = InetAddress.getLocalHost();
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++) {
    ip[3] = (byte)i;
    InetAddress address = InetAddress.getByAddress(ip);
    if (address.isReachable(1000)) {
        System.out.println(address + address.getHostAddress() + address.getAddress() + address.getHostName() + address.getCanonicalHostName());
    }
}

例1 例2

I did in fact find a duplicate (sort of) question, but it hasn't been answered for over a year. 事实上,我确实找到了一个重复(某种)问题,但一年多来都没有回答。 Source 资源

The main problem is that you're grabbing the wrong IP address. 主要问题是你抓错了IP地址。 InetAddress.getLocalHost() is returning 127.0.0.1 and that's just your device. InetAddress.getLocalHost()返回127.0.0.1,那只是你的设备。

Use the Wifi IP address in instead: 改为使用Wifi IP地址:

ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
WifiManager wm = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);

WifiInfo connectionInfo = wm.getConnectionInfo();
int ipAddress = connectionInfo.getIpAddress();
String ipString = Formatter.formatIpAddress(ipAddress);

Here is a quick and dirty AsyncTask that does that: 这是一个快速而肮脏的AsyncTask,它可以做到这一点:

static class NetworkSniffTask extends AsyncTask<Void, Void, Void> {

  private static final String TAG = Constants.TAG + "nstask";

  private WeakReference<Context> mContextRef;

  public NetworkSniffTask(Context context) {
    mContextRef = new WeakReference<Context>(context);
  }

  @Override
  protected Void doInBackground(Void... voids) {
    Log.d(TAG, "Let's sniff the network");

    try {
      Context context = mContextRef.get();

      if (context != null) {

        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        WifiManager wm = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);

        WifiInfo connectionInfo = wm.getConnectionInfo();
        int ipAddress = connectionInfo.getIpAddress();
        String ipString = Formatter.formatIpAddress(ipAddress);


        Log.d(TAG, "activeNetwork: " + String.valueOf(activeNetwork));
        Log.d(TAG, "ipString: " + String.valueOf(ipString));

        String prefix = ipString.substring(0, ipString.lastIndexOf(".") + 1);
        Log.d(TAG, "prefix: " + prefix);

        for (int i = 0; i < 255; i++) {
          String testIp = prefix + String.valueOf(i);

          InetAddress address = InetAddress.getByName(testIp);
          boolean reachable = address.isReachable(1000);
          String hostName = address.getCanonicalHostName();

          if (reachable)
            Log.i(TAG, "Host: " + String.valueOf(hostName) + "(" + String.valueOf(testIp) + ") is reachable!");
        }
      }
    } catch (Throwable t) {
      Log.e(TAG, "Well that's not good.", t);
    }

  return null;
}

Here are the permissions: 以下是权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Not all routers allow this, so to get the names in a other way is to send the mac adress to an api and get the brand name back in return. 并非所有路由器都允许这样做,因此以另一种方式获取名称是将mac地址发送到api并获得品牌名称作为回报。

String macAdress = "5caafd1b0019";
String dataUrl = "http://api.macvendors.com/" + macAdress;
HttpURLConnection connection = null;
try {
    URL url = new URL(dataUrl);
    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    connection.setDoInput(true);
    connection.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
    wr.flush();
    wr.close();
    InputStream is = connection.getInputStream();
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));
    StringBuffer response = new StringBuffer();
    String line;
    while ((line = rd.readLine()) != null) {response.append(line);response.append('\r');}
    rd.close();
    String responseStr = response.toString();
    Log.d("Server response", responseStr);
} catch (Exception e) {e.printStackTrace();} finally {if (connection != null) {connection.disconnect();}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM