Android 获取ip地点多种方式
一、前言
adb shell 的 ifconfig可以获取当前装备网络节点信息;
这些信息利用Android代码也是可以获取的;
Android 获取网络ip有多种方式,有时间某种方式获取失败的情况下;
那么就可以换一种获取方式,全部多学习一下获取网络ip相干信息是有用的。
本文介绍三种获取网络ip信息的方式,并且末了一种的代码不用任何权限就能获取到相干节点的ip和MAC地点,有爱好的可以看看。
二、获取ip地点
1、adb shell ifconfig
- console:/ # ifconfig
- wlan0 Link encap:Ethernet HWaddr 38:64:07:88:6a:f6 Driver usb
- UP BROADCAST MULTICAST MTU:1500 Metric:1
- RX packets:0 errors:0 dropped:0 overruns:0 frame:0
- TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:3000
- RX bytes:0 TX bytes:0
- 。。。
- ap0 Link encap:Ethernet HWaddr 3e:ea:29:0a:07:d9
- inet addr:192.168.43.1 Bcast:192.168.43.255 Mask:255.255.255.0
- inet6 addr: fe80::3cea:29ff:fe0a:7d9/64 Scope: Link
- UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
- RX packets:0 errors:0 dropped:0 overruns:0 frame:0
- TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:1000
- RX bytes:0 TX bytes:1450
复制代码 一般情况热门的节点名称都是ap0,可以看到ip地点和相干信息。
上面的wifi未连接所以才没有ip地点,如果有有线网ip也会表现。
一般情况下网络对应节点名称:
- wifi节点:wlan0,
- 热点:ap0/wlan1,
- 有线网:eth0/eth1
- 投屏节点:p2p
复制代码 2、Android 代码获连接的wifi 的 ip地点:
- public static String getWifiIpAddress(Context context) {
- WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
-
- if (!wifiManager.isWifiEnabled()) {
- // Wi-Fi is not enabled, return null or handle the case accordingly
- return null;
- }
-
- int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
- byte[] bytes = new byte[4];
- for (int i = 0; i < 4; ++i) {
- bytes[i] = (byte)(ipAddress >> ((3 - i) * 8));
- }
-
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append((b & 0xFF)).append(".");
- }
- sb.deleteCharAt(sb.length() - 1);
-
- return sb.toString();
- }
复制代码 要调用这段代码并获得Wifi的 IP 地点,只需传入一个有效的 Context 对象作为参数即可。
当然获取wifi网络另有其他方法,可以继续往下看看。
3、获取有线网的ip
- //获取有线网的ip地址
- public static String getEthernetIpAddress(Context context) {
- LogUtil.debugInform("");
- final Network network = getFirstEthernet(context);
- if (network == null) {
- return "";
- }
- ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- final LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
- if (linkProperties != null) {
- for (LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
- InetAddress inetAddress = linkAddress.getAddress();
- if (inetAddress instanceof Inet4Address) {
- return inetAddress.getHostAddress();
- }
- }
- }
- return "";
- }
- private static Network getFirstEthernet(Context context) {
- ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- final Network[] networks = connectivityManager.getAllNetworks();
- for (final Network network : networks) {
- NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
- //关键:判断网络类型 有线网
- if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
- return network;
- }
- }
- return null;
- }
复制代码 利用这个方法也可以获取wifi的ip地点;修改成wifi类型判断就行了。
利用这个方法必须保证已经连接上了这个网才气查到对应的类型的ip。
网络类型定义:
package\modules\Connectivity\framework\src\android\net\ConnectivityManager.java
- public static final int TYPE_MOBILE = 0; //SIM卡 网络
- public static final int TYPE_WIFI = 1; //wifi 网络
- public static final int TYPE_MOBILE_MMS = 2;
- public static final int TYPE_MOBILE_SUPL = 3;
- public static final int TYPE_MOBILE_DUN = 4;
- public static final int TYPE_MOBILE_HIPRI = 5;
- public static final int TYPE_WIMAX = 6;
- public static final int TYPE_BLUETOOTH = 7;
- public static final int TYPE_DUMMY = 8;
- public static final int TYPE_ETHERNET = 9;//有线网网络
复制代码 4、Android 代码获取全部网络节点的ip地点和MAC地点:
热门没有相干暴露获取的api;
Android 热门ip地点 IpServer 和相干的类都是隐蔽的所以无法上Wifi那样通过api获取到ip地点;
但是可以通过遍历节点的数据,获取到ip地点,
wifi、有线网、热门的ip地点和节点相干的信息都可以如许获取到:
- /**
- * 获取ip地址,key为网络端口名称,比如wlan0、eth0、ap0等,value为ip地址,以及节点相关的MAC地址
- *
- * @return 键值对
- */
- private HashMap<String, String> getNetIPs() {
- HashMap<String, String> hashMap = new HashMap<>();
- try {
- for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
- NetworkInterface intf = en.nextElement(); //打印的信息和 ifconfig 的大致对应
- Log.i(TAG, "----》getEtherNetIP inf = " + intf); //eth0、wifi...
- for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
- InetAddress inetAddress = enumIpAddr.nextElement();
- if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
- Log.i(TAG, "----》getEtherNetIP intf.getName() = " + intf.getName());
- Log.i(TAG, "----》getEtherNetIP inetAddress = " + inetAddress);
- Log.i(TAG, "----》getEtherNetIP inetAddress getHostAddress = " + inetAddress.getHostAddress());
- byte[] hardwareAddress = intf.getHardwareAddress();
-
- //节点对应的ip地址
- hashMap.put(intf.getName(), "" + inetAddress.getHostAddress());
- //节点对应的MAC地址,mac地址是byte数值数据,要转换成字符串
- String mac = bytesToString(hardwareAddress);
- hashMap.put(intf.getName() + "-MAC", "" + mac);
- }
- }
- }
- } catch (SocketException ex) {
- Log.e(TAG, "getEtherNetIP = " + ex.toString());
- }
- return hashMap;
- }
-
- //字节数据转换成字符串
- public static String bytesToString(byte[] bytes) {
- if (bytes == null || bytes.length == 0) {
- return null;
- }
- StringBuilder buf = new StringBuilder();
- for (byte b : bytes) {
- buf.append(String.format("%02X:", b));
- }
- if (buf.length() > 0) {
- buf.deleteCharAt(buf.length() - 1);
- }
- return buf.toString();
- }
复制代码 所以下面这个方法对于很多场景都是可用的。
上面方法在节点名称保存了ip地点和对应的MAC地点;
可以根据需求进行适当修改处理。
上面是获取了ifconfig信息 节点上 Inet4Address 类型的全部信息。
如果只要获取热门的ip地点,可以如许写:
Android 代码获取热门的 ip地点:
主要代码:
- /**
- * 获取热点ip地址字符串
- */
- private String getHotspottIPs() {
- try {
- for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
- NetworkInterface intf = en.nextElement(); //打印的信息和 ifconfig 的大致对应
- Log.i(TAG, "----》getEtherNetIP inf = " + intf); //eth0、wifi...
- for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
- InetAddress inetAddress = enumIpAddr.nextElement();
- if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address && "ap0".equals(intf.getName())) { //判断热点的节点名称ap0,如果不是ap0,就自己修改
- return "" + inetAddress.getHostAddress();
- }
- }
- }
- } catch (SocketException ex) {
- Log.e(TAG, "getEtherNetIP = " + ex.toString());
- }
- return "";
- }
-
复制代码 上面的获取热门ip的方法,是不用Context对象,不用权限,
平凡应用就能调用和获取到信息,验证过是ok的。
所以WiFi、有线网这些网络的ip地点也可以参考如许获取;
需要知道当前体系网络的节点的具体情况,热门节点不一定用ap0,也有的体系利用wlan1的。
三、其他
1、ip地点获取小结
adb shell ifconfig 可以看到当前装备网络节点情况。
获取网络ip的方式有几种:
- 1、获取wifi 的ip
- 可以通过 WifiManager 获取当前连接的wifi信息,获取到ip地址;
- 2、获取有线网、wifi的ip
- 通过获取 ConnectivityManager获取连接的网络 Network-->LinkProperties获取到ip地址。
- 3、获取有线网、wifi、热点、p2p的ip
- 通过获取所有节点信息:NetworkInterface.getNetworkInterfaces() 获取对应的ip地址和MAC地址。
复制代码 前面两种方式都是需要相应权限的,第二种估计要体系签名才可以获取到;
只有第三种不需要任何权限,平凡应用就可以获取到;
但是第一和第二种方式是不需要知道节点名称的,第三种是需要知道节点名称的;
所以如果有体系权限,第一和第二种方式,对于全部平台方案都是可用的;
第三种方案可能对于差别平台方案要进行适配;
因为差别平台的热门和有线网等网络的节点可能差别,但是大部门都是雷同的。
第三种方式是信息量最多的。
2、热门开启流程
体系源码追踪:
- 1、ConnectivityManager.startTethering
- 2、TetheringManager.startTethering
- 3、TetheringService.TetheringConnector.startTethering
- 4、Tethering.startTethering(request, listener);
- 5、WifiManager.startTetheredHotspot(null /* use existing softap config */)
- 6、WifiServiceImpl.startTetheredHotspot(@Nullable SoftApConfiguration softApConfig)
- 7、ActiveModeWarden.startSoftAp(apModeConfig);
- 8、ActiveModeManager.start();
- 10、WifiNative.startSoftAp
- 11、HostapdHal.addAccessPoint
复制代码 热门开启流程原文链接:
https://blog.csdn.net/wenzhi20102321/article/details/128473734
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |