Android13 设置固定热点ip地址192.168.43.1

04-13 阅读 0评论

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

                Android13 设置固定热点ip地址192.168.43.1,Android13 设置固定热点ip地址192.168.43.1,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,方法,设置,接口,第1张
                (图片来源网络,侵删)

                如果要设置成一个固定的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地址就可以了。

                Android13 设置固定热点ip地址192.168.43.1,Android13 设置固定热点ip地址192.168.43.1,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,方法,设置,接口,第2张
                (图片来源网络,侵删)

                从代码大致可以看到,如果未做修改的情况这里热点的默认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

                Android13 设置固定热点ip地址192.168.43.1,Android13 设置固定热点ip地址192.168.43.1,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,方法,设置,接口,第3张
                (图片来源网络,侵删)
                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 > ((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


免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]