赞
踩
[TOC]
Android 有些情况会有修改热点信息的需求,比如修改热点默认名称、默认密码登信息。
之前也有介绍过通过Java系统具体源码修改热点默认配置:
https://blog.csdn.net/wenzhi20102321/article/details/127737534
但是Android13 或者更新的代码,外销国外的设备都要通过EDLA验证了,集成谷歌那套代码,
无法修改 packages\modules\Wifi 的代码,所以无法修改热点的默认信息?
其实办法肯定还是有的,只要在系统第一次启动时通过WifiMannager接口获取wifi信息,再修改一次热点的信息即可。
如果有需求都可以看看下面的实现代码。修改热点其他默认信息也可以同样参考。
Android11 之前的代码修改位置:
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiApConfigStore.java
//Android13 或者更新的代码中修改热点配置文件位置:
packages\modules\Wifi\service\java\com\android\server\wifi\WifiApConfigStore.java
热点密码定义的部分代码如下:
//获取默认热点信息 private SoftApConfiguration getDefaultApConfiguration() { SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); configBuilder.setBand(SoftApConfiguration.BAND_2GHZ); //默认2.4G //名称: configBuilder.setSsid(mContext.getResources().getString( R.string.wifi_tether_configure_ssid_default) + "_" + getRandomIntForDefaultSsid()); if (ApConfigUtil.isWpa3SaeSupported(mContext)) { configBuilder.setPassphrase(generatePassword(), SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); } else { configBuilder.setPassphrase(generatePassword(), SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); //默认热点加密都是WPA2_PSK类型 } return configBuilder.build(); } //获取默认密码信息 private static String generatePassword() { // Characters that will be used for password generation. Some characters commonly known to // be confusing like 0 and O excluded from this list. final String allowed = "23456789abcdefghijkmnpqrstuvwxyz"; final int passLength = 15; StringBuilder sb = new StringBuilder(passLength); SecureRandom random = new SecureRandom(); for (int i = 0; i < passLength; i++) { sb.append(allowed.charAt(random.nextInt(allowed.length()))); } return sb.toString(); }
如果密码需要修改固定字符串,修改这里就可以。
//设置热点密码 public static void setHotspotPassword(Context context, int type, String password) { DebugLog.info("type = " + type + ", password = " + password); WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); SoftApConfiguration config = wifiManager.getSoftApConfiguration(); //获取以前的信息 try { SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); configBuilder.setSsid("" + config.getSsid()); configBuilder.setPassphrase(password, type); if (config.getChannel() != 0) { configBuilder.setChannel(config.getChannel(), config.getBand()); } else { configBuilder.setBand(config.getBand()); } SoftApConfiguration finalConfig = configBuilder.build(); DebugLog.info("finalConfig = " + finalConfig); wifiManager.setSoftApConfiguration(finalConfig); } catch (Exception e) { DebugLog.error("error = " + e.getMessage()); } }
上面就是应用中设置热点信息的代码,需要一些网络权限、还有系统uid签名才能正常调用。
热点的类型没有wifi那么多,只有三种类型:
type数值和对应类型定义
0:无密码,不能设置密码字符串;
1: 普通类型,WPA、WPA2;
2:WPA3,需要设备硬件支持,一般要Android11以上设备。
上面的代码除了可以设置热点密码和类型,如果有需求还可以定义热点名称、热点信道值channel、热点频段band。
//设置热点默认密码
boolean isNeedSetHotspotPassword = SystemProperties.getBoolean("persist.debug.need_set_hotspot_password", true);
if (isNeedSetHotspotPassword) {
String hotspotPassword = SystemProperties.get("persist.debug.hotspot_password_defalut", "abcd1234");
FunctionUtil.setHotspotPassword(mContext, 1, hotspotPassword);
SystemProperties.set("persist.debug.need_set_hotspot_password", "false");
}
上面代码设置看一个属性,保证只会设置一次热点信息。
具体实现,已经在上面“应用代码中修改热点配置信息”片段有介绍。
这里的代码仅供参考,很多实际项目会有开机向导应用oobe,也可以使用oobe相关属性做第一次设置。
密码字符串长度小于8或者大于63 也会报错。
看如下代码:
package\modules\Wifi\framework\java\android\net\wifi\SoftApConfiguration.java
public Builder setPassphrase(@Nullable String passphrase, @SecurityType int securityType) { if (securityType == SECURITY_TYPE_OPEN) { if (passphrase != null) { throw new IllegalArgumentException( "passphrase should be null when security type is open"); } } else { Preconditions.checkStringNotEmpty(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } if (securityType == SECURITY_TYPE_WPA2_PSK || securityType == SECURITY_TYPE_WPA3_SAE_TRANSITION) { if (passphrase.length() < PSK_MIN_LEN || passphrase.length() > PSK_MAX_LEN) { throw new IllegalArgumentException( "Password size must be at least " + PSK_MIN_LEN + " and no more than " + PSK_MAX_LEN + " for WPA2_PSK and WPA3_SAE_TRANSITION Mode"); } } } return this; }
还是上面那个 SoftApConfiguration.java
public Builder setChannel(int channel, @BandType int band) { if (!isChannelBandPairValid(channel, band)) { throw new IllegalArgumentException("Invalid band type"); } mBand = band; mChannel = channel; return this; } //channel和band的简单校验 private static boolean isChannelBandPairValid(int channel, @BandType int band) { switch (band) { case BAND_2GHZ: //不能小于1 和大于14 if (channel < MIN_CH_2G_BAND || channel > MAX_CH_2G_BAND) { return false; } break; case BAND_5GHZ://不能小于34 和大于196 if (channel < MIN_CH_5G_BAND || channel > MAX_CH_5G_BAND) { return false; } break; case BAND_6GHZ://不能小于1 和大于253 if (channel < MIN_CH_6G_BAND || channel > MAX_CH_6G_BAND) { return false; } break; default: return false; } return true; } //如果值设置band,就简单很多,1,2,4三个值。实际设置3也不会报错。 public Builder setBand(@BandType int band) { if (!isBandValid(band)) { throw new IllegalArgumentException("Invalid band type"); } mBand = band; // Since band preference is specified, no specific channel is selected. mChannel = 0; return this; }
上面代码看如果设置错误的频道band和信道channel也是会抛出异常。
如果不确定信道值channel,那么就只设置band就行了,系统framework内部会自动选择一个可用的channel值。
channel值是一定不能为0的,即使获取之前的配置信息是0,设置的时候不能设置0,设置band值就行。
针对Android系统源码,我这里主要开发过Android8、9、11、13、14.
Android8和9 是差不多的,Android13和14是差不多的;
Android10和12没有接触不做评论。
估计啊:Android10和11差不多,12和13差不多。
这里只说一下很简单的两点:
(1)文件目录变化
Android11 之前的代码修改位置:
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiApConfigStore.java
//Android13 或者更新的代码中修改热点配置文件位置:
packages\modules\Wifi\service\java\com\android\server\wifi\WifiApConfigStore.java
(2)设置热点信息调用api变化
变化如下:
//Android9 或者更低版本的代码:
WifiConfiguration wifiConfig;
WifiManager.setWifiApConfiguration(wifiConfig);
//Android11 或者更新版本的代码:
SoftApConfiguration softApConfiguration = wifiManager.getSoftApConfiguration();
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
configBuilder.setSsid(mHotspotName);
...
WifiConfiguration config = configBuilder.build();
WifiManager.setSoftApConfiguration(config);
https://blog.csdn.net/wenzhi20102321/article/details/128593458
https://blog.csdn.net/wenzhi20102321/article/details/128507254
https://blog.csdn.net/wenzhi20102321/article/details/134349526
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。