状态栏显示的wifi信号强度与wifisetting列表不一致(不同步)

本文分析了设备上WiFi信号强度显示不一致的原因,探讨了状态栏与设置界面间信号更新的不同步现象。提出了解决方案,包括统一信号级别、同步更新机制及优化RSSI计算方法。
[DESCRIPTION]
状态栏显示的wifi信号强度与wifisetting列表不一致(不同步)
 
[ANALYSIS]
1、apk都是接收RSSI_CHANGED intent,并调用WifiManager.calculateSignalLevel()方法计算信号个数
2、WifiSettings界面和状态栏的调用点分别是AccessPoints.java和NetworkController(Gemini).java,可以看到两个地方所传给WifiManager.calculateSignalLevel()的level值不同,一个是4一个是5,所以计算下来有可能格数不一致
3、当处于WifiSettings列表界面时,会6s钟刷新一次信号,定义在WifiSettings.WIFI_RESCAN_INTERVAL_MS
4、状态条刷新的时间是3s,定义在在wifiStatemachine.java中(POLL_RSSI_INTERVAL_MSECS),若信号变化会丢RSSI_CHANGE出来
 
[SOLUTION]
1、把两边的level都改成5级(注意数组不要越界)
2、在wifiSettings接受RSSI_CHANGED消息,之后调用updateAccesspoint把界面和状态条同步更新
3、需要注意的是,假定两边的rssi值一个是-69、一个是-66,送给WifiManager.calculateSignalLevel()的计算值会有区别:
31 × 4 / 45 = 124 / 45 = 2.xxx
34 × 4 / 45 = 136 / 45 = 3.xxx
这种情况下可以按rssi范围返回level值,减少浮点数转int带来的误差,比如:
if(rssi 在-55和-65之间)返回4
if(rssi 在-65和-75之间)返回xxx
 
function WirelessRepeater({}) { // 模拟扫描到的无线网络数据 const initialScanData = { scanning: false, networks: [ { ssid: "HomeWiFi_5G", bssid: "11:22:33:44:55:66", signal: 85, security: "wpa2", band: "5GHz", channel: 36 }, { ssid: "Office_Network", bssid: "66:55:44:33:22:11", signal: 72, security: "wpa2", band: "2.4GHz", channel: 6 }, { ssid: "GuestWiFi", bssid: "aa:bb:cc:dd:ee:ff", signal: 45, security: "open", band: "2.4GHz", channel: 1 }, { ssid: "TP-Link_1234", bssid: "12:34:56:78:90:ab", signal: 68, security: "wpa2", band: "5GHz", channel: 149 } ], selectedNetwork: null, reconnectInterval: 300 }; // 中继配置状态 const initialRepeaterConfig = { enabled: false, ssid: "Repeater_Ext", security: "wpa2", password: "", band: "auto", channel_width: "20MHz", tx_power: "80%", hidden: false }; const [scanData, setScanData] = useState(null); const [repeaterConfig, setRepeaterConfig] = useState(null); const [saveResult, setSaveResult] = useState(null); const [isScanning, setIsScanning] = useState(false); const [showAdvanced, setShowAdvanced] = useState(false); // 模拟扫描无线网络 const scanNetworks = () => { setIsScanning(true); return new Promise(resolve => { setTimeout(() => { // 模拟扫描过程中信号强度的随机变化 const updatedNetworks = initialScanData.networks.map(network => ({ ...network, signal: Math.max(20, Math.min(95, network.signal + (Math.random() * 20 - 10))) })); setScanData({ ...initialScanData, networks: updatedNetworks, scanning: false }); setIsScanning(false); resolve(); }, 2000); }); }; // 初始化配置 const refresh = () => { return new Promise(resolve => { setTimeout(() => { setScanData(initialScanData); setRepeaterConfig(initialRepeaterConfig); resolve(); }, 300); }); }; // 选择网络进行中继 const selectNetwork = (network) => { setScanData(prev => ({ ...prev, selectedNetwork: network })); // 自动填充中继配置 setRepeaterConfig(prev => ({ ...prev, ssid: `${network.ssid}_Repeater` })); }; // 配置更新函数 const setRepeaterConfigFn = (key) => (value) => { setRepeaterConfig(prev => ({ ...prev, [key]: value })); }; // 保存中继配置 const saveRepeaterConfig = (ev) => { ev.preventDefault(); fetch('api/repeater/set', { method: 'post', body: JSON.stringify({ config: repeaterConfig, targetNetwork: scanData.selectedNetwork }) }) .then(r => r.json()) .then(r => { setSaveResult(r); // 保存成功后重新扫描网络状态 setTimeout(refresh, 1000); }) .catch(err => { setSaveResult({ status: false, message: '保存失败: ' + err.message }); }); }; // 启动中继功能 const startRepeater = () => { if (!scanData.selectedNetwork) { setSaveResult({ status: false, message: '请先选择要中继的网络' }); return; } setRepeaterConfig(prev => ({ ...prev, enabled: true })); saveRepeaterConfig(new Event('submit')); }; // 停止中继功能 const stopRepeater = () => { setRepeaterConfig(prev => ({ ...prev, enabled: false })); fetch('api/repeater/stop', { method: 'post' }) .then(r => r.json()) .then(r => setSaveResult(r)) .then(refresh); }; // 组件初始化 useEffect(() => { refresh(); }, []); if (!scanData || !repeaterConfig) return '加载中...'; return html` <div class="m-4 grid grid-cols-1 gap-6 lg:grid-cols-2"> <!-- 网络扫描区域 --> <div class="py-1 divide-y border rounded bg-white flex flex-col"> <div class="font-light uppercase flex items-center justify-between text-gray-600 px-4 py-2"> <span>无线网络扫描</span> <div class="flex gap-2"> <${Button} icon=${Icons.refresh} onclick=${scanNetworks} disabled=${isScanning} title="重新扫描" variant="outline" /> <${Button} icon=${Icons.wifi} onclick=${repeaterConfig.enabled ? stopRepeater : startRepeater} variant=${repeaterConfig.enabled ? "danger" : "primary"} title=${repeaterConfig.enabled ? "停止中继" : "启动中继"} /> </div> </div> <div class="py-2 px-4 flex-1 flex flex-col"> ${saveResult && html`<${Notification} ok=${saveResult.status} text=${saveResult.message} close=${() => setSaveResult(null)} />`} <!-- 扫描状态指示 --> <div class="mb-4 p-3 bg-gray-50 rounded flex items-center justify-between"> <span class="text-sm text-gray-600"> ${isScanning ? '扫描中...' : `找到 ${scanData.networks.length} 个网络`} </span> <div class="flex items-center gap-2"> <div class="w-2 h-2 rounded-full ${repeaterConfig.enabled ? 'bg-green-500' : 'bg-gray-400'}"></div> <span class="text-xs">${repeaterConfig.enabled ? '中继运行中' : '中继已停止'}</span> </div> </div> <!-- 网络列表 --> <div class="space-y-2 max-h-96 overflow-y-auto"> ${scanData.networks.map((network, index) => html` <div key=${network.bssid} class="p-3 border rounded cursor-pointer transition-all hover:bg-blue-50 ${scanData.selectedNetwork?.bssid === network.bssid ? 'border-blue-500 bg-blue-50' : 'border-gray-200'}" onclick=${() => selectNetwork(network)}> <div class="flex items-center justify-between"> <div class="flex items-center gap-3"> <div class="w-8 h-8 flex items-center justify-center bg-gray-100 rounded"> ${network.security === 'open' ? html`<${Icons.unlock} />` : html`<${Icons.lock} />`} </div> <div> <div class="font-medium">${network.ssid}</div> <div class="text-xs text-gray-500">${network.bssid}</div> </div> </div> <div class="text-right"> <div class="flex items-center gap-1"> <${SignalStrength} strength=${network.signal} /> <span class="text-sm font-mono">${network.signal}%</span> </div> <div class="text-xs text-gray-500">${network.band} · 信道 ${network.channel}</div> </div> </div> </div> `)} </div> </div> </div> <!-- 中继配置区域 --> <div class="py-1 divide-y border rounded bg-white flex flex-col"> <div class="font-light uppercase flex items-center justify-between text-gray-600 px-4 py-2"> <span>中继配置</span> <${Button} icon=${Icons.settings} onclick=${() => setShowAdvanced(!showAdvanced)} title=${showAdvanced ? "隐藏高级设置" : "显示高级设置"} variant="outline" /> </div> <div class="py-2 px-4 flex-1 flex flex-col"> ${scanData.selectedNetwork ? html` <div class="mb-4 p-3 bg-green-50 border border-green-200 rounded"> <div class="font-medium text-green-800">已选择网络中继</div> <div class="text-sm text-green-600">${scanData.selectedNetwork.ssid}</div> </div> ` : html` <div class="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded"> <div class="text-sm text-yellow-800">请从左侧列表选择要中继的网络</div> </div> `} <${Setting} title="启用无线中继" value=${repeaterConfig.enabled} setfn=${setRepeaterConfigFn('enabled')} type="switch" /> <${Setting} title="中继SSID" value=${repeaterConfig.ssid} setfn=${setRepeaterConfigFn('ssid')} type="text" disabled=${!scanData.selectedNetwork} description="中继后网络的名称" /> <${Setting} title="安全模式" value=${repeaterConfig.security} setfn=${setRepeaterConfigFn('security')} type="select" options=${['open', 'wpa', 'wpa2', 'wpa3']} disabled=${!scanData.selectedNetwork} /> <${Setting} title="无线密码" value=${repeaterConfig.password} setfn=${setRepeaterConfigFn('password')} type="password" disabled=${!scanData.selectedNetwork || repeaterConfig.security === 'open'} placeholder=${repeaterConfig.security === 'open' ? '开放网络无需密码' : '输入无线密码'} /> ${showAdvanced && html` <div class="border-t pt-3 mt-3"> <div class="text-sm font-medium text-gray-700 mb-3">高级设置</div> <${Setting} title="频段选择" value=${repeaterConfig.band} setfn=${setRepeaterConfigFn('band')} type="select" options=${['auto', '2.4GHz', '5GHz']} /> <${Setting} title="信道宽度" value=${repeaterConfig.channel_width} setfn=${setRepeaterConfigFn('channel_width')} type="select" options=${['20MHz', '40MHz', '80MHz']} /> <${Setting} title="发射功率" value=${repeaterConfig.tx_power} setfn=${setRepeaterConfigFn('tx_power')} type="select" options=${['25%', '50%', '80%', '100%']} /> <${Setting} title="隐藏网络" value=${repeaterConfig.hidden} setfn=${setRepeaterConfigFn('hidden')} type="switch" /> </div> `} <div class="mb-1 mt-3 flex place-content-end gap-2"> <${Button} icon=${Icons.refresh} onclick=${refresh} title="重置配置" variant="outline" /> <${Button} icon=${Icons.save} onclick=${saveRepeaterConfig} title="保存设置" disabled=${!scanData.selectedNetwork} /> </div> </div> </div> </div> <!-- 状态信息栏 --> ${repeaterConfig.enabled && scanData.selectedNetwork && html` <div class="mt-4 p-3 bg-blue-50 border border-blue-200 rounded"> <div class="flex items-center justify-between"> <div> <div class="font-medium text-blue-800">无线中继运行中</div> <div class="text-sm text-blue-600"> 中继网络: ${scanData.selectedNetwork.ssid} → ${repeaterConfig.ssid} </div> </div> <${Button} icon=${Icons.stop} onclick=${stopRepeater} title="停止中继" variant="danger" size="sm" /> </div> </div> `} `; } 这个卡在 正在从服务器加载无线中继配置... 模拟API请求中 怎么解决
最新发布
12-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值