Android 实现热点开机后自动开启

Android 实现热点开机后自动开启

文章目录

一、前言

Android 热点是有api设置永久开启,热点名称,热点密码等接口,但是"永久开启"实际上是不自动关闭,重启设备后热点并不会自动开启。

Android Wifi实现开关状态记忆是基于Settings.GLOBAL.WIFI_ON属性,

所以热点如果要实现状态记忆那么也是要设置一个Settings属性或者prop属性,

系统启动后判断属性决定是否启动热点就可以实现热点状态记忆了。

Android Wifi有自己的服务WifiService和服务实现WifiServiceImpl,

热点是没有对应服务的,那怎么办呢?大致有两种方法可以解决。

二、实现方式

1、在 WifiServiceImpl 启动热点

热点操作其实同样在 WifiServiceImpl 判断处理即可,因为热点的api实现很多也是封装在WifiServiceImpl 里面的。

packages\modules\Wifi\service\java\com\android\server\wifi\WifiServiceImpl.java

复制代码
import android.os.SystemProperties; //记得导包

/**
 * WifiService handles remote WiFi operation requests by implementing
 * the IWifiManager interface.
 */
public class WifiServiceImpl extends BaseWifiService {

    //系统服务启动后判断Wifi的逻辑方法
    public void checkAndStartWifi() {
        //根据wifi 属性判断是否启动wifi
        mWifiThreadRunner.post(() -> {
。。。
            // Check if wi-fi needs to be enabled
            boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
            Log.i(TAG,"WifiService starting up with Wi-Fi " + (wifiEnabled ? "enabled" : "disabled")); //可以看到这里是有个打印的
。。。
            }
        }

        //根据热点 属性判断是否启动热点
        mWifiThreadRunner.postDelayed(() -> {
                    boolean isHotspotEnable = SystemProperties.getBoolean("persist.skg.hotspot.enable", false);
                    Log.d(TAG, "checkAndStartWifi start ap isHotspotEnable = " + isHotspotEnable);
                    if (isHotspotEnable) {
                        startTetheredHotspot(getSoftApConfiguration(), mContext.getPackageName());
                    }
                },
                100);//延时一下比较好,避免wifi启动未处理完成
    }
}

开机后抓的WifiService 关键字的 logcat 日志:

复制代码
console:/ # logcat | grep WifiService   
12-14 17:34:21.258   639   639 I SystemServiceManager: Starting com.android.server.wifi.WifiService
12-14 17:34:21.289   639   639 I WifiService: Registering wifi
//wifi是否启动日志
12-14 17:34:21.910   639   803 I WifiService: WifiService starting up with Wi-Fi enabled
...
//自己添加的热点是否需要启动的日志
12-14 18:33:35.902   639   803 D WifiService: checkAndStartWifi start ap isHotspotEnable = true
12-14 18:33:35.903   639   803 I WifiService: startTetheredHotspot uid=1000
...
12-14 18:33:36.011   639   803 D WifiService: updateInterfaceIpState: ifaceName=ap0 mode=1 previous LOHS mode= -1
12-14 18:33:36.636   639   863 I WifiService: acquireMulticastLock uid=1000
12-14 18:33:39.621   639   803 D WifiService: handleBootCompleted---mIsBootComplete---true

2、在开机广播中开启热点

Android 原生广播:

Intent.ACTION_BOOT_COMPLETED = android.intent.action.BOOT_COMPLETED

应用接收到开机广播后,开启热点:

复制代码
boolean isHotspotEnable = SystemProperties.getBoolean("persist.skg.hotspot.enable", false);
Log.d(TAG, "checkAndStartWifi start ap isHotspotEnable = " + isHotspotEnable);
if (isHotspotEnable) {
    ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    mConnectivityManager.startTethering(TETHERING_WIFI, true, null, new Handler(Looper.getMainLooper()));
}

但是开机广播有些方案上会比较慢,有些要界面显示后还要等半分钟左右才才收到开机广播。

这种情况一般是静态接收开机广播的情况,广播优先级并未提高,系统多个接收广播的地方有耗时处理导致。

开机广播慢解决的方法:

复制代码
1、自定义开机广播,不用等所有的系统服务启动完成就发出该广播

BOOT_COMPLETED 也是在 UserController.java 里面发出的,可以在之前发出自定义广播,

会比所有的 BOOT_COMPLETED 广播都快,但是需要对系统启动有一定的了解,避免写出bug

frameworks\base\services\core\java\com\android\server\am\UserController.java

2、静态广播提高优先级

<receiver android:name=".MyReceiver">
    <intent-filter android:priority="1000">
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

3、动态注册开机广播

开机广播也是可以动态注册的,一般是在自己定义的系统服务内进行监听,会比静态广播收到更早。

三、其他

1、热点开机自启动方式总结

复制代码
(1)系统服务启动的时候启动热点

(2)开机广播启动热点

怎么设置自己定义的属性,上面并没有讲,因为我这边的系统一般都是自己的设置应用,在设置应用点击开关的时候设置那个属性就行了。

但是如果全是用的原生的应用呢,并且要保证其他app开关热点能够同步信息,就要在热点启动流程里面设置那个属性了, 代码:TetheringManager startTethering 和 stopTethering ,具体流程可以往下看看。

2、热点开启流程

https://blog.csdn.net/wenzhi20102321/article/details/128473734

3、热点启动相关日志

看了上面启动流程,可以发现热点最重要的日志是在 SoftApManager 里面

复制代码
logcat -c ;logcat | grep -E "TetheringManager|SoftApManager" 
//(1)调用开启热点接口和应用包名
12-19 14:38:01.748  1902  7767 I TetheringManager: startTethering caller:com.my.settings

//(2)热点开启成功
12-19 14:38:01.966   949  1267 D SoftApManager[ap0]: Soft AP is started
//(3)热点部分信息
12-19 14:38:02.430   949  1267 D SoftApManager[ap0]: SoftApInfo update SoftApInfo{bandwidth= 3, frequency= 5745,bssid=be:05:dc:cb:ae:86, wifiStandard= 5, mApInstanceIdentifier= ap0, mIdleShutdownTimeoutMillis= 600000}, isRemoved: false
12-19 14:38:02.431   949  1267 D SoftApManager[ap0]: rescheduleTimeoutMessageIfNeeded ap0, timeoutEnabled=true, isChargingfalse, clientNumber=0
//(4)热点10分钟后自动关闭
12-19 14:38:02.434   949  1267 D SoftApManager[ap0]: Timeout message scheduled, on ap0, delay = 600000

//(5)调用热点关闭和应用包名
12-19 14:38:11.244  1902  1902 I TetheringManager: stopTethering caller:com.my.settings
//(6)热点关闭成功
12-19 14:38:11.556   949  1267 D SoftApManager[ap0]: Soft AP is stopped
12-19 14:38:11.559   949  1267 D SoftApManager[ap0]: Timeout message canceled on ap0
12-19 14:38:11.569   949  1267 V WifiActiveModeWarden: ModeManager removed SoftApManager{id=547203 iface=null role=null}

4、其他热点相关知识分享

都是一些自己开发中遇到的知识记录:

Android11 热点设置永不关闭

Android11 设置默认热点 名称和热点密码、密码长度

Android11 热点配置信息保存分析

Android13分享热点设置安全性为wpa3

Android11 热点Band值为3

Android11 Wifi 加密类型详解

相关推荐
大白的编程日记.27 分钟前
【MySQL】数据库表的CURD(二)
android·数据库·mysql
迎風吹頭髮1 小时前
Linux服务器编程实践30-TCP交互数据流:Nagle算法与延迟确认的作用
网络
介一安全1 小时前
【Frida Android】基础篇4:Java层Hook基础——调用静态方法
android·网络安全·逆向·安全性测试·frida
怪兽20141 小时前
主线程 MainLooper 和一般 Looper 的异同?
android·面试
洋不写bug2 小时前
数据库的创建,查看,修改,删除,字符集编码和校验操作
android·数据库·adb
2501_915909063 小时前
iOS App 上架全流程详解:证书配置、打包上传、审核技巧与跨平台上架工具 开心上架 实践
android·ios·小程序·https·uni-app·iphone·webview
2501_915106323 小时前
iOS 26 系统流畅度测试实战分享,多工具组合辅助策略
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_915918413 小时前
开发 iOS 应用全流程指南,环境搭建、证书配置与跨平台使用 开心上架 上架AppStore
android·ios·小程序·https·uni-app·iphone·webview
思想是一切事物的源头3 小时前
渗透测试所需域名和IP信息收集方法
网络·网络协议·tcp/ip·安全性测试
灵芸小骏3 小时前
Rokid应用实践:基于CXR-M与CXR-S SDK,打造眼镜与手机协同的‘智能随行记录仪’
android