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 加密类型详解

相关推荐
Kapaseker1 小时前
你一定会喜欢的 Compose 形变动画
android
QuZhengRong1 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
zhangphil2 小时前
Android Coil3视频封面抽取封面帧存Disk缓存,Kotlin(2)
android·kotlin
程序员码歌9 小时前
【零代码AI编程实战】AI灯塔导航-总结篇
android·前端·后端
七七&5569 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
元清加油10 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
书弋江山10 小时前
flutter 跨平台编码库 protobuf 工具使用
android·flutter
向日葵.12 小时前
fastdds.ignore_local_endpoints 属性
服务器·网络·php
来来走走13 小时前
Flutter开发 webview_flutter的基本使用
android·flutter
Jerry说前后端13 小时前
Android 组件封装实践:从解耦到架构演进
android·前端·架构