Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
398 views
in Technique[技术] by (71.8m points)

java - 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. 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.

I have searched a lot on google and stackoverflow, but nothing seemed to work for me. Even GitHub has no effective code. I tried searching for UPnP, Local Area Network, subnets, etc, but found nothing.

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());
    }
}

Example 1 Example 2

I did in fact find a duplicate (sort of) question, but it hasn't been answered for over a year. Source

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The main problem is that you're grabbing the wrong IP address. InetAddress.getLocalHost() is returning 127.0.0.1 and that's just your device.

Use the Wifi IP address in instead:

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:

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.

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('
');}
    rd.close();
    String responseStr = response.toString();
    Log.d("Server response", responseStr);
} catch (Exception e) {e.printStackTrace();} finally {if (connection != null) {connection.disconnect();}}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...