Android13 设置固定热点ip地址192.168.43.1

您所在的位置:网站首页 手机网卡ip地址怎么设置 Android13 设置固定热点ip地址192.168.43.1

Android13 设置固定热点ip地址192.168.43.1

2024-07-11 17:24| 来源: 网络整理| 查看: 265

Android13 设置固定热点ip地址192.168.43.1

文章目录 Android13 设置固定热点ip地址192.168.43.1一、前言二、设置固定ip地址实现1、Android13 代码中的实现:添加属性写法: 2、Android11 或者更旧的代码中的实现: 三、其他1、Android 代码获连接的wifi 的 ip地址:2、获取热点的ip地址(1)adb 获取ip地址(2)Android 代码获取所有网络的ip地址和MAC地址:(3)Android 代码获取热点的 ip地址:(4)动态设置热点ip的代码?(5)热点开启流程

一、前言

Android 热点ip一般的系统都是随机生成的,地址一般是:192.168.XX.XX

如果要设置成一个固定的ip地址,就需要适配系统代码。

相关的适配代码主要都在 IpServer.java 里面。

为啥要设置固定热点ip? 一般是投屏软件需求,或者其他一些开机或者打开热点后被自动连接场景的需求。

二、设置固定ip地址实现 1、Android13 代码中的实现:

release\packages\modules\Connectivity\Tethering\src\android\net\ip\IpServer.java

private boolean configureIPv4(boolean enabled) { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); if (enabled) { //以前的随机的ip地址 //mIpv4Address = requestIpv4Address(true /* useLastAddress */); //换成自定义的ip地址 mIpv4Address = new LinkAddress("192.168.43.1/24"); } 。。。。 }

就是这么简单,设置一下开启热点前请求到的ipv4地址就可以了。

从代码大致可以看到,如果未做修改的情况这里热点的默认ip是从上一次存在的热点ip,当然第一次还是随机生成的。

添加属性写法:

如果要添加属性判断设置,后期可以动态修改,那么可以设置一下prop属性。具体修改如下:

import android.os.SystemProperties; private boolean configureIPv4(boolean enabled) { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); if (enabled) { //set hotspot addr of this constant by liwenzhi boolean isRandomIp = SystemProperties.getBoolean("persist.sys.dubug.random_hostip", false); if (isRandomIp) { mIpv4Address = requestIpv4Address(true /* useLastAddress */); } else { //默认是固定ip mIpv4Address = new LinkAddress("192.168.43.1/24"); } } 。。。。 } 2、Android11 或者更旧的代码中的实现:

release\frameworks\base\packages\Tethering\src\android\net\ip\IpServer.java

private boolean configureIPv4(boolean enabled) { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); if (enabled) { //以前的随机的ip地址 //mIpv4Address = requestIpv4Address(); //换成自定义的ip地址 mIpv4Address = new LinkAddress("192.168.43.1/24"); } }

不同版本上,代码的修改都是差不多的,只是 IpServer.java 这个类的位置有改变。

3、Android13 获取热点ip的过程

release\packages\modules\Connectivity\Tethering\src\android\net\ip\IpServer.java

private boolean configureIPv4(boolean enabled) { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); if (enabled) { mIpv4Address = requestIpv4Address(true /* useLastAddress */); } 。。。。 } private final PrivateAddressCoordinator mPrivateAddressCoordinator; private LinkAddress requestIpv4Address(final boolean useLastAddress) { if (mStaticIpv4ServerAddr != null) return mStaticIpv4ServerAddr; if (shouldNotConfigureBluetoothInterface()) return new LinkAddress(BLUETOOTH_IFACE_ADDR); //在其他对象中获取 return mPrivateAddressCoordinator.requestDownstreamAddress(this, useLastAddress); }

所以具体实现是在 PrivateAddressCoordinator 对象的 requestDownstreamAddress 方法中。

release\packages\modules\Connectivity\Tethering\src\com\android\networkstack\tethering\PrivateAddressCoordinator.java

/** * Pick a random available address and mark its prefix as in use for the provided IpServer, * returns null if there is no available address. */ @Nullable public LinkAddress requestDownstreamAddress(final IpServer ipServer, boolean useLastAddress) { if (mConfig.shouldEnableWifiP2pDedicatedIp() && ipServer.interfaceType() == TETHERING_WIFI_P2P) { return new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS); } final LinkAddress cachedAddress = mCachedAddresses.get(ipServer.interfaceType()); if (useLastAddress && cachedAddress != null && !isConflictWithUpstream(asIpPrefix(cachedAddress))) { mDownstreams.add(ipServer); return cachedAddress; } for (IpPrefix prefixRange : mTetheringPrefixes) { final LinkAddress newAddress = chooseDownstreamAddress(prefixRange); if (newAddress != null) { mDownstreams.add(ipServer); mCachedAddresses.put(ipServer.interfaceType(), newAddress); return newAddress; } } // No available address. return null; }

有兴趣的可以自己在源码中查看,Android11 和Android13 的具体获取过程有很大的差异。

上面就是本文的主要内容,下面是其他相关内容,有兴趣可以继续看看。

三、其他 1、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(); }

要调用这段代码并获得热点的 IP 地址,只需传入一个有效的 Context 对象作为参数,然后调用 getWifiIpAddress() 方法即可。

2、获取热点的ip地址 (1)adb 获取ip地址

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地址。

(2)Android 代码获取所有网络的ip地址和MAC地址:

Android 热点ip地址 IpServer 和相关的类都是隐藏的所以无法上Wifi那样通过api获取到ip地址,

但是可以通过遍历节点的数据,获取到ip地址,

wifi、有线网、热点的ip地址和节点相关的信息都可以这样获取到:

/** * 获取ip地址,key为网络端口名称,比如wlan0、eth0、ap0等,value为ip地址,以及节点相关的MAC地址 * * @return 键值对 */ private HashMap getNetIPs() { HashMap hashMap = new HashMap(); try { for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); //打印的信息和 ifconfig 的大致对应 Log.i(TAG, "----》getEtherNetIP inf = " + intf); //eth0、wifi... for (Enumeration 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(); }

上面是获取了ifconfig信息 节点上 Inet4Address 类型的所有信息,如果只要获取热点的ip地址,可以这样写:

(3)Android 代码获取热点的 ip地址:

主要代码:

/** * 获取热点ip地址字符串 */ private String getHotspottIPs() { try { for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); //打印的信息和 ifconfig 的大致对应 Log.i(TAG, "----》getEtherNetIP inf = " + intf); //eth0、wifi... for (Enumeration 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地址也可以参考这样获取。

网上搜到的通过 ConnectivityManager 获取WifiManager 相关接口获取的代码,都是获取不到热点ip地址的。

即使通过反射也是无法获取到热点相关信息的,因为不仅相关方法是隐藏的,相关类也是被隐藏的,

所以一般的反射手段是无法获取到热点ip的。

(4)动态设置热点ip的代码?

从网上其他文章上看到这样一段设置热点ip的代码:

InterfaceConfiguration ifcg = mNwService.getInterfaceConfig(intf); if (ifcg != null) { /* IP/netmask: 192.168.43.1/255.255.255.0 */ ifcg.setLinkAddress(new LinkAddress( NetworkUtils.numericToInetAddress("192.168.43.1"), 24)); ifcg.setInterfaceUp(); mNwService.setInterfaceConfig(intfaceName, ifcg); //intfaceName 是节点名称,比如"ap0" }

在普通应用试了下是没有 InterfaceConfiguration这个类的,需要那些导入了framework的系统才可以找到这些类和调用这些api。

这个段代码并没有进行尝试,怀疑是不一定能设置到固定的ip的;

因为开启热点不是这种代码,还需要配置相关信息的;

并且尝试ifconfig ap0 down再,ifconfig ap0 up,默认是没有热点ip的,

所以不经过某些系统流程是无获取到ip地址的。

有兴趣的可以自己尝试研究看看。

(5)热点开启流程

系统源码追踪:

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3