Android 13 修改热点密码
[TOC]
一、前言
Android 有些情况会有修改热点信息的需求,比如修改热点默认名称、默认密码登信息。
之前也有介绍过通过Java系统具体源码修改热点默认配置:
https://blog.****.net/wenzhi20102321/article/details/127737534
但是Android13 或者更新的代码,外销国外的设备都要通过EDLA验证了,集成谷歌那套代码,
无法修改 packages\modules\Wifi 的代码,所以无法修改热点的默认信息?
其实办法肯定还是有的,只要在系统第一次启动时通过WifiMannager接口获取wifi信息,再修改一次热点的信息即可。
如果有需求都可以看看下面的实现代码。修改热点其他默认信息也可以同样参考。
二、修改热点密码代码
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
热点密码定义的部分代码如下:
//获取默认热点信息
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();
}
如果密码需要修改固定字符串,修改这里就可以。
2、应用代码中修改热点配置信息
//设置热点密码
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。
三、其他
1、Android13 系统启动后修改热点信息示例
//设置热点默认密码
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相关属性做第一次设置。
2、热点配置信息注意点
(1)热点密码类型如果设置成0,密码字符串不能设置非空字符串,否则会报错;
密码字符串长度小于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;
}
(2)热点频段和信道值设置要正确否则会报错
还是上面那个 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值就行。
3、Android几个版本热点的修改点
针对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);
4、Android11 热点配置信息保存分析
https://blog.****.net/wenzhi20102321/article/details/128593458
5、Android11 热点Band值为3
https://blog.****.net/wenzhi20102321/article/details/128507254
6、Android13分享热点设置安全性为wpa3
https://blog.****.net/wenzhi20102321/article/details/134349526