Android11 热点设置永不关闭
Posted 峥嵘life
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android11 热点设置永不关闭相关的知识,希望对你有一定的参考价值。
android11 热点设置永不关闭
文章目录
一、前言
Android 热点默认是10 分钟后没有设备关联是会自动关闭,如果需要设置默认不关闭热点可以有几种方式。
二、framework设置热点永不超时关闭
查阅网上资料Android 的做法:
找到:
CMD_NO_ASSOCIATED_STATIONS_TIMEOUT //超时后触发消息,关闭热点
修改:
case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT:
break;这样永远就走不到关闭热点的逻辑
在Android11 framwrok grep 遍历发现CMD_NO_ASSOCIATED_STATIONS_TIMEOUT 有的。
所以在 case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT: 添加 break;跳过关闭逻辑同样是生效的
代码位置:
frameworks\\opt\\net\\wifi\\service\\java\\com\\android\\server\\wifi\\SoftApManager.java
//找到如下代码进行修改即可:
case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT:
//添加break 即可完成跳过自动关闭热点逻辑。
if (true)
Log.i(TAG, "timeout but no to close hotspot ap!");
break;
if (mConnectedClients.size() != 0)
Log.wtf(TAG, "Timeout message received but has clients. Dropping.");
break;
mSoftApNotifier.showSoftApShutDownTimeoutExpiredNotification();
Log.i(TAG, "Timeout message received. Stopping soft AP.");
updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
WifiManager.WIFI_AP_STATE_ENABLED, 0);
transitionTo(mIdleState);
break;
其实最好还是添加一个系统属性,可以动态设置是否自动关闭热点。
import android.os.SystemProperties;
//获取
boolean isSanitizeChannel = SystemProperties.getBoolean("persisit.hotspot_auto_close", false);
//设置
SystemProperties.set("key", bool + "");
三、基于 SoftApManager.java 研究超时逻辑
从热点开启ConnectivityManager.startTethering 到 SoftApManager.start(),
这个流程不在这里描述,有兴趣可以自己看看。
这里只看超时相关的代码。
public class SoftApManager implements ActiveModeManager
//内部类,不用在意里面真正消息处理,父类内部有Handler处理。
private class SoftApStateMachine extends StateMachine
// Commands for the state machine.
public static final int CMD_START = 0;
public static final int CMD_STOP = 1;
public static final int CMD_FAILURE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
public static final int CMD_ASSOCIATED_STATIONS_CHANGED = 4;
public static final int CMD_NO_ASSOCIATED_STATIONS_TIMEOUT = 5; //超时消息
。。。
//内部类的内部类!
private class StartedState extends State
private WakeupMessage mSoftApTimeoutMessage;
private void scheduleTimeoutMessage()
if (!mTimeoutEnabled || mConnectedClients.size() != 0)
cancelTimeoutMessage();
return;
long timeout = mApConfig.getSoftApConfiguration().getShutdownTimeoutMillis();
if (timeout == 0)
timeout = mDefaultShutDownTimeoutMills;
//(2)发送延时消息,成功打开热点会触发
//可以看到这里是当前时间+timeout时间,重点是研究timeout时间
mSoftApTimeoutMessage.schedule(SystemClock.elapsedRealtime()+ timeout);
Log.d(TAG, "Timeout message scheduled, delay = "+ timeout);
private void cancelTimeoutMessage()
//(3)关闭延时消息,关闭热点会触发
mSoftApTimeoutMessage.cancel();
Log.d(TAG, "Timeout message canceled");
@Override
public void enter()
mIfaceIsUp = false;
mIfaceIsDestroyed = false;
onUpChanged(mWifiNative.isInterfaceUp(mApInterfaceName));
Handler handler = mStateMachine.getHandler();
mSoftApTimeoutMessage = new WakeupMessage(mContext, handler,
SOFT_AP_SEND_MESSAGE_TIMEOUT_TAG,
SoftApStateMachine.CMD_NO_ASSOCIATED_STATIONS_TIMEOUT); //(1)超时Message创建,调用启动热点会触发
mSarManager.setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED);
Log.d(TAG, "Resetting connected clients on start");
mConnectedClients.clear();
mEverReportMetricsForMaxClient = false;
scheduleTimeoutMessage();
@Override
public boolean processMessage(Message message)
switch (message.what)
case CMD_ASSOCIATED_STATIONS_CHANGED:
if (!(message.obj instanceof NativeWifiClient))
Log.e(TAG, "Invalid type returned for"
+ " CMD_ASSOCIATED_STATIONS_CHANGED");
break;
case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT:
if (!mTimeoutEnabled)
Log.wtf(TAG, "Timeout message received while timeout is disabled."
+ " Dropping.");
break;
case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT: //真正处理超时关闭热点的代码
if (!mTimeoutEnabled)
Log.wtf(TAG, "Timeout message received while timeout is disabled." + " Dropping.");
break;
。。。
mSoftApNotifier.showSoftApShutDownTimeoutExpiredNotification();
Log.i(TAG, "Timeout message received. Stopping soft AP.");
updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
WifiManager.WIFI_AP_STATE_ENABLED, 0);
transitionTo(mIdleState);
break;
从上面代码看重点是超时设置重点是看:
long timeout = mApConfig.getSoftApConfiguration().getShutdownTimeoutMillis();
if (timeout == 0)
timeout = mDefaultShutDownTimeoutMills;
//(2)发送延时消息,成功打开热点会触发
//可以看到这里是当前时间+timeout时间,重点是研究timeout时间
mSoftApTimeoutMessage.schedule(SystemClock.elapsedRealtime()+ timeout);
1、mApConfig.getSoftApConfiguration().getShutdownTimeoutMillis();
一看就是获取某个long数值,查看一下SoftApConfiguration.java 对象是否有相关方法,
查看确实有set 和 get方法,是hide、SystemApi方法,说明系统应用中是可以设置热点超时时间的。
/**
* Delay in milliseconds before shutting down soft AP when
* there are no connected devices.
*/
private final long mShutdownTimeoutMillis;
@NonNull
public Builder setShutdownTimeoutMillis(@IntRange(from = 0) long timeoutMillis)
if (timeoutMillis < 0)
throw new IllegalArgumentException("Invalid timeout value");
mShutdownTimeoutMillis = timeoutMillis;
return this;
/**
* Returns the shutdown timeout in milliseconds.
* The Soft AP will shutdown when there are no devices associated to it for
* the timeout duration. See @link Builder#setShutdownTimeoutMillis(long).
*
* @hide
*/
@SystemApi
public long getShutdownTimeoutMillis()
return mShutdownTimeoutMillis;
如果配置对象中没有设置数据的情况,那么就要看mDefaultShutDownTimeoutMills值了。
if (timeout == 0)
timeout = mDefaultShutDownTimeoutMills;
还是 SoftApManager.java的代码
private long mDefaultShutDownTimeoutMills;
//构造方法中:
public SoftApManager (...)
...
mDefaultShutDownTimeoutMills = mContext.getResources().getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
继续追config_wifiFrameworkSoftApShutDownTimeoutMilliseconds定义的文件:
frameworks\\opt\\net\\wifi\\service\\res\\values\\config.xml
<!-- Integer delay in milliseconds before shutting down soft AP when there
are no connected devices. -->
<integer translatable="false" name="config_wifiFrameworkSoftApShutDownTimeoutMilliseconds">600000</integer>
所以 mDefaultShutDownTimeoutMills 的默认值是60000,600秒,即10分钟。
三、总结:
1、设置热点不关闭的方法:
(1)在SoftApManager.java 找到case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT
直接break;或者retrun;跳过后续关闭热点操作。
(2)设置热点开启时间长度
在资源配置文件中设置超时时间为永久:2147483647 (Int的最大数值)
<integer translatable="false" name="config_wifiFrameworkSoftApShutDownTimeoutMilliseconds">2147483647</integer>
####(3)在代码开启热点的对象设置超时时间
//设置无密码,10信道,2.4G的热点信号
public void setHotspot2_4(View view)
private WifiManager mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
//使用Build形式配置对象
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
configBuilder.setSsid(mHotspotName);
configBuilder.setChannel(10, SoftApConfiguration.BAND_2GHZ);
//30 分钟:30*60*1000 = 1800000 或者永久 2147483647
configBuilder.setShutdownTimeoutMillis(2147483647);
mWifiManager.setSoftApConfiguration(configBuilder.build());
有试过setShutdownTimeoutMillis 方法设置30 分钟的时间,发现过了30分钟没自动关闭!
具体原因,可以再源码中添加打印查看哈。
2、其他
* 热点配置信息对象
* Android11 使用 WifiManager.setWifiApConfiguration(config); 已经过期,使用已经不能生效!
* 需要使用:WifiManager.setSoftApConfiguration(config);
具体实现可以看:
frameworks\\opt\\net\\wifi\\service\\java\\com\\android\\server\\wifi\\WifiServiceImpl.java
虽然最终都是调用:mWifiApConfigStore.setApConfiguration(softApConfig)
但是 setSoftApConfiguration 有更多的健全逻辑,比如:全局更新配置
mActiveModeWarden.updateSoftApConfiguration(softApConfig);
具体不做分析!
以上是关于Android11 热点设置永不关闭的主要内容,如果未能解决你的问题,请参考以下文章
我用android的手机开便携式Wlan热点!屏幕锁定后就断开网络了,该怎么操作!