当前位置: 首页 > news >正文

uni-app-x开发安卓app的wifi监听器实战

UniApp X 安卓App的Wi-Fi 状态监听器实战指南

前言

在移动应用开发中,实时监听 Wi-Fi 连接状态变化是一个常见需求。本文将详细介绍如何使用 UniApp X (UTS) 开发一个健壮的 Wi-Fi 状态监听器,帮助开发者快速实现网络状态检测功能。

功能特性

  • 监听 Wi-Fi 开关状态变化(开启/关闭)
  • 监听网络连接状态变化(连接/断开)
  • 自动获取当前连接的 Wi-Fi 名称(SSID)
  • 单例模式设计,避免重复注册监听器
  • 自动释放资源,防止内存泄漏

权限配置

在使用 Wi-Fi 功能之前,需要在AndroidManifest.xml中配置相应权限:

<!-- Wi-Fi 权限 --><uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/><uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"/><!-- 获取 SSID 所需的位置权限 --><uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/><uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>

注意:在 Android 8.0 及以上版本,获取 Wi-Fi SSID 名称需要位置权限。即使应用本身不需要位置功能,也必须申请此权限才能获取到真实的 SSID。

核心代码实现

必须先申请android.permission.ACCESS_FINE_LOCATION 权限 再进行下一步 这里就不写了

// wifiListener.utsimportContextfrom"android.content.Context";importIntentfrom"android.content.Intent";importIntentFilterfrom"android.content.IntentFilter";importBroadcastReceiverfrom"android.content.BroadcastReceiver";importWifiManagerfrom"android.net.wifi.WifiManager";importWifiInfofrom"android.net.wifi.WifiInfo";importNetworkInfofrom"android.net.NetworkInfo";typeWifiStateData={isConnected:boolean;ssid?:string;}// 获取SSID 需要配置权限 android.permission.ACCESS_FINE_LOCATION 即app的位置权限开启 才能获取到 必须先申请权限classWifiBroadcastReceiverextendsBroadcastReceiver{privatecb:(data:WifiStateData)=>void;constructor(callback:(data:WifiStateData)=>void){super();this.cb=callback;}overrideonReceive(context:Context,intent:Intent){constaction=intent.getAction();if(action===WifiManager.WIFI_STATE_CHANGED_ACTION){conststate=intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,WifiManager.WIFI_STATE_UNKNOWN);if(state===WifiManager.WIFI_STATE_ENABLED){console.log('[Wi-Fi] 已开启');constssid=getCurrentSSID();consthasSsid=ssid!=null;if(hasSsid){this.cb({isConnected:true,ssid:ssid});}else{this.cb({isConnected:false});}}elseif(state===WifiManager.WIFI_STATE_DISABLED){console.log('[Wi-Fi] 已关闭');this.cb({isConnected:false});}}elseif(action===WifiManager.NETWORK_STATE_CHANGED_ACTION){constnetworkInfo=intent.getParcelableExtra<NetworkInfo>(WifiManager.EXTRA_NETWORK_INFO);if(networkInfo!=null&&networkInfo.isConnected()){constwifiInfo=intent.getParcelableExtra<WifiInfo>(WifiManager.EXTRA_WIFI_INFO);letssid:string|null=null;if(wifiInfo!=null){constraw=wifiInfo.getSSID();if(raw!=null&&raw!=='<unknown ssid>'){ssid=raw.replace(/^"|"$/g,'');}}if(ssid==null){ssid=getCurrentSSID();}console.log('[Wi-Fi] 已连接:',ssid!=null?ssid:'未知网络');if(ssid!=null){this.cb({isConnected:true,ssid:ssid});}else{this.cb({isConnected:true});}}else{console.log('[Wi-Fi] 已断开');this.cb({isConnected:false});}}}}/** * Wi-Fi 状态监听器 * 使用方法: * const listener = WifiListener.getInstance(); * listener.startListening((state) => { console.log(state); }); * // 页面销毁时:listener.stopListening(); */classWifiListener{privatestaticinstance:WifiListener|null=null;privatereceiver:BroadcastReceiver|null=null;privatecontext:Context|null=null;privateconstructor(){}publicstaticgetInstance():WifiListener{if(WifiListener.instance==null){WifiListener.instance=newWifiListener();}returnWifiListener.instance;}privategetContext():Context|null{if(this.context==null){this.context=UTSAndroid.getAppContext();}returnthis.context;}/** * 开始监听 Wi-Fi 状态变化 * @param callback 回调函数,参数为 { isConnected: boolean, ssid?: string } */publicstartListening(callback:(data:WifiStateData)=>void):void{constcontext=this.getContext();if(context==null){console.error('无法获取 Context');return;}this.stopListening();this.receiver=newWifiBroadcastReceiver(callback);constfilter=newIntentFilter();filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);try{context.registerReceiver(this.receiver,filter);console.log('[Wi-Fi] 监听器已注册');}catch(e){console.error('[Wi-Fi] 注册失败:',e);}}/** * 停止监听,取消注册广播接收器 */publicstopListening():void{if(this.receiver!=null){constcontext=this.getContext();if(context!=null){try{context.unregisterReceiver(this.receiver);console.log('[Wi-Fi] 监听器已取消注册');}catch(e){}}this.receiver=null;}}}functiongetCurrentSSID():string|null{constcontext=UTSAndroid.getAppContext();if(context==null)returnnull;constwifiManager=context.getSystemService(Context.WIFI_SERVICE)asWifiManager;if(wifiManager==null)returnnull;constwifiInfo=wifiManager.getConnectionInfo();if(wifiInfo==null)returnnull;if(wifiInfo.getNetworkId()===-1)returnnull;letssid=wifiInfo.getSSID();if(ssid!=null&&ssid!=='<unknown ssid>'){ssid=ssid.replace(/^"|"$/g,'');returnssid;}returnnull;}export{WifiListener,WifiStateData};

使用示例

在页面中使用

<template> <view> <view>Wi-Fi 状态: {{ isConnected ? '已连接' : '未连接' }}</view> <view v-if="ssid">网络名称: {{ ssid }}</view> </view> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue'; import { WifiListener } from '@/utils/wifiHelper.uts'; const isConnected = ref(false); const ssid = ref(''); const wifiListener = WifiListener.getInstance(); onMounted(() => { wifiListener.startListening((state) => { isConnected.value = state.isConnected; ssid.value = state.ssid || ''; }); }); onUnmounted(() => { wifiListener.stopListening(); }); </script>

技术要点解析

1. 为什么需要继承 BroadcastReceiver

Android 的 Wi-Fi 状态变化通过广播机制传递。BroadcastReceiver是 Android 四大组件之一,用于接收系统广播。要监听 Wi-Fi 状态,必须:

  • 创建BroadcastReceiver的子类
  • 重写onReceive方法处理广播
  • AndroidManifest.xml或代码中注册接收器

2. 为什么要使用单例模式

privatestaticinstance:WifiListener|null=null;publicstaticgetInstance():WifiListener{if(WifiListener.instance==null){WifiListener.instance=newWifiListener();}returnWifiListener.instance;}
  • 避免重复创建监听器实例
  • 确保全局只有一个广播接收器
  • 防止多次注册导致的资源浪费

3. SSID 获取的注意事项

functiongetCurrentSSID():string|null{constwifiInfo=wifiManager.getConnectionInfo();if(wifiInfo.getNetworkId()===-1)returnnull;letssid=wifiInfo.getSSID();if(ssid!=null&&ssid!=='<unknown ssid>'){ssid=ssid.replace(/^"|"$/g,'');returnssid;}returnnull;}
  • SSID 返回值可能包含引号,需要去除
  • <unknown ssid>表示无法获取真实的 SSID
  • getNetworkId() === -1表示未连接到任何网络

常见问题

Q: 为什么 SSID 返回 “”?

A: 这是 Android 的安全机制。在 Android 8.0 及以上版本,第三方应用获取 SSID 需要满足以下条件:

  1. 位置权限已授予
  2. 定位服务已开启
  3. 应用具有ACCESS_FINE_LOCATION权限

Q: 如何处理权限申请?

参考 https://blog.csdn.net/a3212768093/article/details/161656845?spm=1001.2014.3001.5501

总结

本文详细介绍了使用 UniApp X 的 UTS 开发 Android 原生 Wi-Fi 监听器的方法。通过封装单例模式的WifiListener类,开发者可以方便地在应用任何页面监听 Wi-Fi 状态变化,无需关心广播接收器的注册和注销细节。

关键技术点:

  • 使用BroadcastReceiver接收系统广播
  • 单例模式确保全局唯一监听器
  • 正确处理权限和边界情况
  • 记得在页面销毁时停止监听
http://www.jsqmd.com/news/1069299/

相关文章:

  • 基于STM32F103的WIFI体感遥控小车工程包(含MPU6050姿态解算与OLED实时状态显示)
  • 构建软件供应链安全日报:从漏洞监控到风险预警的自动化实践
  • WooCommerce:WordPress 上的开源电商方案
  • 当年薛海涛说得多漂亮,今天上汽通用高端车的保值率就跌得有多狠
  • 本地离线 AI 自动化 OpenClaw 2.7.9 实测,文件批量处理与浏览器操控实操
  • SP-RACING-F3 飞控电路图
  • MajorDoMo未授权RCE漏洞深度剖析:从命令注入到批量PoC实战
  • 基于TestHub的接口自动化测试框架:从分层设计到CI/CD集成实战
  • 3步掌握碧蓝航线自动化:Alas智能助手解放你的游戏时间
  • 跟着 MDN 学无障碍 Day 7:WAI-ARIA 基础
  • 三工位联动在换料频繁工序中的效率提升分析
  • Android逆向实战:Hook dlopen绕过Frida检测机制
  • ppt模板_0109_红橙世界
  • K9s:在终端里管 Kubernetes,不用再反复敲 kubectl
  • 山东展馆多媒体咨询电话怎么联系?
  • 浏览器解析HTML头部的底层逻辑技术
  • 企业数字化转型107页PPT,这份规划设计太绝了!
  • 华玺AI观察:华玺云科认为,全球市场智能体不是多语种翻译工具
  • Excel撑不起一家成长中的企业
  • 自动化运维平台搭建指南
  • 企业信息化升级,OA系统助力高效办公
  • 科技轻养生实测|磁灸共振仪到底好不好用?半年真实使用复盘
  • 从普通中走丝换到自动穿丝,FPC模具良品率从八成提到九成半
  • 程序化广告系列 (6):交易模式(下)——Header Bidding 的革命
  • 2026 国内智能问数厂商盘点:BI 原生、云厂商、行业场景与信创方案对比
  • 如何用XUnity.AutoTranslator为Unity游戏实现高效自动化翻译
  • 广州市即闪科技有限公司口碑
  • 售前PPT怎么写才不翻车?这份避坑指南讲透了
  • pyquery:Python版jQuery,让HTML解析更顺手
  • 虚实同构全域算力底座 构建营区空间数字孪生透明智管生态,镜像视界·空间元境营区全维度穿透式智能管控体系技术总案