Java 如何在Android上获取本地网络中所有设备的IP地址和名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39335835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get IP address and names of all devices in local network on Android
提问by Jason
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.
我想用java查看我网络上所有连接的设备,但我无法让它工作。我在下面附上了一些我希望它如何输出的屏幕截图。我想要名称(例如“TP Link Router”或“Nexus 5X”)和 IP 地址。
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.
我在 google 和 stackoverflow 上搜索了很多,但似乎没有什么对我有用。甚至 GitHub 也没有有效的代码。我尝试搜索 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());
}
}
I did in fact find a duplicate (sort of) question, but it hasn't been answered for over a year. Source
事实上,我确实找到了一个重复的(某种)问题,但已经一年多没有人回答了。来源
采纳答案by DataDino
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.
主要问题是您获取了错误的 IP 地址。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();}}