[最新]Android 热点(HotSpot) 开关检测

问题背景:

需求是实时检测android手机的热点是否打开,网上百度,谷歌都是:
1).主动检测:通过反射去WifiManager类的getWifiApState方法或者isWifiApEnabled方法的值
2).被动检测:动态注册监听广播android.net.wifi.WIFI_AP_STATE_CHANGED,然后判断值是否为11(关闭)/13(打开)
此二方法可适配现在大部分新手机,但是我遇到了一台华为手机(为鸿蒙系统)主动检测一直是false,且不触发被动广播,大写的郁闷!!

问题原因:

经详细查询,这个问题是一个技术变迁导致的问题,手机wifi网卡同一时间只能处于一种状态下(连接wifi上网/做为ap提供网络);
现在比较新的手机支持双网卡,比如小米新款机型,就能实现wifi不断地情况在开ap;
而有些手机只有一张网卡,因此打开热点就只能关闭wifi,这个时候触发的广播其实是android.net.conn.TETHER_STATE_CHANGED,这个广播里面会包含当前支持ap的有那几个接口availableArray,现在激活的是哪个接口tetherArray;其中接口大概有:p2p0, wlan0, p2p-p2p0-6, wlan1, ap0等;

我通过对比三台手机监听android.net.conn.TETHER_STATE_CHANGED这个广播对比发现出问题的华为手机打开/关闭热点tetherArray有变化,因此根据这个特点对原主动检测方法做了兼容处理,完美解决问题,下面是日志记录(其中华为nova 7为问题机型,日志中的标识在最下面的代码里可查看):

华为畅享9(DUB-AL100,Emui系统)
2022-08-31 14:34:58.533 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:34:58.535 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:34:58.537 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:55.764 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:36:55.771 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:55.822 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:36:55.830 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:56.113 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:36:56.118 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:56.153 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:36:56.157 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:56.176 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:56.326 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:36:56.334 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:36:57.107 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:36:57.142 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[]===active:[wlan0]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:36:57.148 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:37:30.121 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:30.210 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:30.215 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:30.272 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:30.705 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:30.712 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:31.018 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:31.027 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:31.047 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:31.052 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:43.002 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:43.007 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:43.063 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:43.069 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:43.417 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:43.421 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:43.444 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:43.448 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:43.467 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:43.591 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:43.596 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:44.375 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:37:44.432 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[]===active:[wlan0]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:44.435 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:37:50.461 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:50.521 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:50.525 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:50.609 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:51.006 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:51.011 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:51.341 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:51.345 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:37:51.379 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:37:51.382 1291-1291/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false

华为nova 7(JEF-AN00,harmony系统)
2022-08-31 14:39:30.234 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0, p2p-p2p0-5]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:39:30.238 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:39:30.316 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[p2p-p2p0-5]====>error:[]===>isCompatCheckApOpen:true
2022-08-31 14:39:30.327 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:39:46.010 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:39:46.017 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:39:46.018 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:39:46.022 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:39:48.999 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0, p2p-p2p0-6]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:39:49.004 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:39:49.104 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[p2p-p2p0-6]====>error:[]===>isCompatCheckApOpen:true
2022-08-31 14:39:49.111 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:39:53.152 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:39:53.156 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:39:53.167 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[p2p0, wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:39:53.170 17044-17044/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false

小米Civi(miui系统)
2022-08-31 14:59:28.038 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:28.039 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:59:28.041 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:36.294 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0, wlan1]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:59:36.302 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:36.331 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:36.459 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:59:36.519 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[wlan1]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:59:36.522 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:59:38.702 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:38.805 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:59:38.808 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:39.092 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:40.940 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0, wlan1]===active:[]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:59:40.951 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:40.967 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>false/false
2022-08-31 14:59:41.034 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true
2022-08-31 14:59:41.072 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:[wlan0]===active:[wlan1]====>error:[]===>isCompatCheckApOpen:false
2022-08-31 14:59:41.075 8569-8569/com.xxxxx.xxxx.xxxxx I/System.out: ======Stephen=======HotSpotStateReceiver==>true/true

解决代码(isHotSpotApOpen()和isHotSpotApOpen2()二选一即可):

//注册广播
val intentFilter = IntentFilter()
intentFilter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED")
intentFilter.addAction("android.net.conn.TETHER_STATE_CHANGED")
hotSpotStateReceiver = HotSpotStateReceiver()
activity.registerReceiver(hotSpotStateReceiver, intentFilter)
//响应广播
class HotSpotStateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action
        if (action == "android.net.wifi.WIFI_AP_STATE_CHANGED") {
            when(intent.getIntExtra("wifi_state", 0)){//便携式热点的状态为:10---正在关闭;11---已关闭;12---正在开启;13---已开启
                10 -> EventBus.getDefault().post(MsgOperationEvent(MsgOperationEvent.MsgHotSpotChangeState, -1))//正在关闭
                11 -> EventBus.getDefault().post(MsgOperationEvent(MsgOperationEvent.MsgHotSpotChangeState, 0))//已关闭
                12 -> EventBus.getDefault().post(MsgOperationEvent(MsgOperationEvent.MsgHotSpotChangeState, -2))//正在开启
                13 -> EventBus.getDefault().post(MsgOperationEvent(MsgOperationEvent.MsgHotSpotChangeState, 1))//已开启
            }
        } else if (action == "android.net.conn.TETHER_STATE_CHANGED") {
            val available = intent.getStringArrayListExtra("availableArray")
            val active = intent.getStringArrayListExtra("tetherArray")
            val error = intent.getStringArrayListExtra("erroredArray")
            Utils.isCompatCheckApOpen = !active.isNullOrEmpty()
            Utils.debugPrintln("======Stephen=======HotSpotStateReceiver==TETHER_STATE_CHANGED====available:$available===active:$active====>" +
                    "error:$error===>isCompatCheckApOpen:${UtilsJava.isCompatCheckApOpen}")
            EventBus.getDefault().post(MsgOperationEvent(MsgOperationEvent.MsgHotSpotChangeState, if(UtilsJava.isCompatCheckApOpen) 1 else 0))
        }
      Utils.debugPrintln("======Stephen=======HotSpotStateReceiver==>"+UtilsJava.isHotSpotApOpen(context)+"/"+UtilsJava.isHotSpotApOpen2(context))
    }
}
//UtilsJava
//获取热点是否打开方式1
public static boolean isHotSpotApOpen(Context context) {
    var isAPEnable = false;
    try {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        Method method = wifiManager.getClass().getDeclaredMethod("getWifiApState");
        int state = (int) method.invoke(wifiManager);
        Field field = wifiManager.getClass().getDeclaredField("WIFI_AP_STATE_ENABLED");
        int value = (int) field.get(wifiManager);
        isAPEnable = state == value;
    } catch (Exception e) {
        e.printStackTrace();
    }
    if(!isAPEnable && isCompatCheckApOpen) isAPEnable = true;
    return isAPEnable;
}

//某些华为鸿蒙机型(比如JEF-AN00)需要兼容处理
public static boolean isCompatCheckApOpen = false;

//获取热点是否打开方式2
public static boolean isHotSpotApOpen2(Context context) {
    var isAPEnable = false;
    try {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        Method method = wifiManager.getClass().getDeclaredMethod("isWifiApEnabled");
        method.setAccessible(true);
        isAPEnable = (Boolean) method.invoke(wifiManager);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if(!isAPEnable && isCompatCheckApOpen) isAPEnable = true;
    return isAPEnable;
}

你可能感兴趣的:([最新]Android 热点(HotSpot) 开关检测)