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.
如果要设置成一个固定的ip地址,就需要适配系统代码。
相关的适配代码主要都在 里面。
为啥要设置固定热点ip?
一般是投屏软件需求,或者其他一些开机或者打开热点后被自动连接场景的需求。
二、设置固定ip地址实现
1、Android13 代码中的实现:
release\packages\modules\Connectivity\Tethering\src\android\net\ip\
private boolean configureIPv4(boolean enabled) {
if (VDBG) (TAG, "configureIPv4(" + enabled + ")");
if (enabled) {
//以前的随机的ip地址
//mIpv4Address = requestIpv4Address(true /* useLastAddress */);
//换成自定义的ip地址
mIpv4Address = new LinkAddress("192.168.43.1/24");
}
。。。。
}
就是这么简单,设置一下开启热点前请求到的ipv4地址就可以了。
从代码大致可以看到,如果未做修改的情况这里热点的默认ip是从上一次存在的热点ip,当然第一次还是随机生成的。
添加属性写法:
如果要添加属性判断设置,后期可以动态修改,那么可以设置一下prop属性。具体修改如下:
import ;
private boolean configureIPv4(boolean enabled) {
if (VDBG) (TAG, "configureIPv4(" + enabled + ")");
if (enabled) {
//set hotspot addr of this constant by liwenzhi
boolean isRandomIp = (".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\
private boolean configureIPv4(boolean enabled) {
if (VDBG) (TAG, "configureIPv4(" + enabled + ")");
if (enabled) {
//以前的随机的ip地址
//mIpv4Address = requestIpv4Address();
//换成自定义的ip地址
mIpv4Address = new LinkAddress("192.168.43.1/24");
}
}
不同版本上,代码的修改都是差不多的,只是 这个类的位置有改变。
3、Android13 获取热点ip的过程
release\packages\modules\Connectivity\Tethering\src\android\net\ip\
private boolean configureIPv4(boolean enabled) {
if (VDBG) (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 (this, useLastAddress);
}
所以具体实现是在 PrivateAddressCoordinator 对象的 requestDownstreamAddress 方法中。
release\packages\modules\Connectivity\Tethering\src\com\android\networkstack\tethering\
/**
* 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()
&& () == TETHERING_WIFI_P2P) {
return new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS);
}
final LinkAddress cachedAddress = (());
if (useLastAddress && cachedAddress != null
&& !isConflictWithUpstream(asIpPrefix(cachedAddress))) {
(ipServer);
return cachedAddress;
}
for (IpPrefix prefixRange : mTetheringPrefixes) {
final LinkAddress newAddress = chooseDownstreamAddress(prefixRange);
if (newAddress != null) {
(ipServer);
((), newAddress);
return newAddress;
}
}
// No available address.
return null;
}
有兴趣的可以自己在源码中查看,Android11 和Android13 的具体获取过程有很大的差异。
上面就是本文的主要内容,下面是其他相关内容,有兴趣可以继续看看。
三、其他
1、Android 代码获连接的wifi 的 ip地址:
public static String getWifiIpAddress(Context context) {
WifiManager wifiManager = (WifiManager) ().getSystemService(Context.WIFI_SERVICE);
if (!()) {
// Wi-Fi is not enabled, return null or handle the case accordingly
return null;
}
int ipAddress = ().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) {
((b & 0xFF)).append(".");
}
(() - 1);
return ();
}
要调用这段代码并获得热点的 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<String, String> getNetIPs() {
HashMap<String, String> hashMap = new HashMap<>();
try {
for (Enumeration<NetworkInterface> en = (); (); ) {
NetworkInterface intf = (); //打印的信息和 ifconfig 的大致对应
(TAG, "----》getEtherNetIP inf = " + intf); //eth0、wifi...
for (Enumeration<InetAddress> enumIpAddr = (); (); ) {
InetAddress inetAddress = ();
if (!() && inetAddress instanceof Inet4Address) {
(TAG, "----》getEtherNetIP () = " + ());
(TAG, "----》getEtherNetIP inetAddress = " + inetAddress);
(TAG, "----》getEtherNetIP inetAddress getHostAddress = " + ());
byte[] hardwareAddress = ();
//节点对应的ip地址
((), "" + ());
//节点对应的MAC地址,mac地址是byte数值数据,要转换成字符串
String mac = bytesToString(hardwareAddress);
(() + "-MAC", "" + mac);
}
}
}
} catch (SocketException ex) {
(TAG, "getEtherNetIP = " + ());
}
return hashMap;
}
//字节数据转换成字符串
public static String bytesToString(byte[] bytes) {
if (bytes == null || == 0) {
return null;
}
StringBuilder buf = new StringBuilder();
for (byte b : bytes) {
(("%02X:", b));
}
if (() > 0) {
(() - 1);
}
return ();
}
上面是获取了ifconfig信息 节点上 Inet4Address 类型的所有信息,如果只要获取热点的ip地址,可以这样写:
(3)Android 代码获取热点的 ip地址:
主要代码:
/**
* 获取热点ip地址字符串
*/
private String getHotspottIPs() {
try {
for (Enumeration<NetworkInterface> en = (); (); ) {
NetworkInterface intf = (); //打印的信息和 ifconfig 的大致对应
(TAG, "----》getEtherNetIP inf = " + intf); //eth0、wifi...
for (Enumeration<InetAddress> enumIpAddr = (); (); ) {
InetAddress inetAddress = ();
if (!() && inetAddress instanceof Inet4Address && "ap0".equals(())) { //判断热点的节点名称ap0,如果不是ap0,就自己修改
return "" + ();
}
}
}
} catch (SocketException ex) {
(TAG, "getEtherNetIP = " + ());
}
return "";
}
上面的获取热点ip的方法,是不用Context对象,不用权限,普通应用就能调用和获取到信息,验证过是ok的。
所以WiFi、有线网这些网络的ip地址也可以参考这样获取。
网上搜到的通过 ConnectivityManager 获取WifiManager 相关接口获取的代码,都是获取不到热点ip地址的。
即使通过反射也是无法获取到热点相关信息的,因为不仅相关方法是隐藏的,相关类也是被隐藏的,
所以一般的反射手段是无法获取到热点ip的。
(4)动态设置热点ip的代码?
从网上其他文章上看到这样一段设置热点ip的代码:
InterfaceConfiguration ifcg = (intf);
if (ifcg != null) {
/* IP/netmask: 192.168.43.1/255.255.255.0 */
(new LinkAddress(
("192.168.43.1"), 24));
();
(intfaceName, ifcg); //intfaceName 是节点名称,比如"ap0"
}
在普通应用试了下是没有 InterfaceConfiguration这个类的,需要那些导入了framework的系统才可以找到这些类和调用这些api。
这个段代码并没有进行尝试,怀疑是不一定能设置到固定的ip的;
因为开启热点不是这种代码,还需要配置相关信息的;
并且尝试ifconfig ap0 down再,ifconfig ap0 up,默认是没有热点ip的,
所以不经过某些系统流程是无获取到ip地址的。
有兴趣的可以自己尝试研究看看。
(5)热点开启流程
系统源码追踪:
1、
2、
3、
4、(request, listener);
5、(null /* use existing softap config */)
6、(@Nullable SoftApConfiguration softApConfig)
7、(apModeConfig);
8、();
10、
11、
热点开启流程原文链接:
/wenzhi20102321/article/details/128473734