从Android framework层实现实现wifi无缝切换AP
2015-12-03 15:43
555 查看
Android市场上有一款叫Wifijumper的软件,实现相同ssid的多个AP之间根据wifi信号的强弱与阀值进行判断,实现自动切换AP的功能。目前在android4.2之前系统都没有该功能,对于google来讲,这是个相当简单的问题,不明白为什么一直都不支持该功能。鄙人之前在某个方案公司就遇到过客户需要该功能。以下是鄙人实现的具体过程,希望对大家有些许的帮助。
首先我们必须时刻监听当前wifi的信号强度,那么我们的手机连上wifi之后状态兰就会有wifi图标出来,并且信号强度变化信号格也要跟随变化,这部分工作是在SystemUI完成的。在目录
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
这个类就是SystemUI监听网络连接状态的Receiver。
在OnReceive方法中
调用了 updateWifiState(Intent intent)方法,那么我们的切换功能就可以放到这个updateWifiState方法中:
添加一下代码:
逻辑其实很简单,就是根据当前ssid去扫描的列表中找相同ssid的ap如果有,就找信号最强的,当最强的那个信号比当前的信号超过一定的值时,断开重连。当然这种做法还是效率不是高的。原因就是当你在不停的移动中,传过来的信号值其实和当前的实际值有一定的差异。
首先我们必须时刻监听当前wifi的信号强度,那么我们的手机连上wifi之后状态兰就会有wifi图标出来,并且信号强度变化信号格也要跟随变化,这部分工作是在SystemUI完成的。在目录
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
这个类就是SystemUI监听网络连接状态的Receiver。
在OnReceive方法中
if ( action.equals( WifiManager.RSSI_CHANGED_ACTION ) || action.equals( WifiManager.WIFI_STATE_CHANGED_ACTION ) || action.equals( WifiManager.NETWORK_STATE_CHANGED_ACTION ) ) { updateWifiState( intent ); refreshViews(); }
调用了 updateWifiState(Intent intent)方法,那么我们的切换功能就可以放到这个updateWifiState方法中:
mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); mWifiLevel = WifiManager.calculateSignalLevel( mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT);
添加一下代码:
+import android.net.wifi.ScanResult; /* 导入包 */ boolean isWorking = false; if ( mWifiConnected ) { WifiInfo wifiInfo = ( (WifiManager) mContext.getSystemService( Context.WIFI_SERVICE ) ).getConnectionInfo(); /* ---- */ if ( (wifiInfo != null) && !isWorking ) { String curentSSID = wifiInfo.getSSID(); String currentBssid = wifiInfo.getBSSID(); Log.e( TAG, "updateWifiState curentSSID == " + curentSSID + " currentBssid = " + currentBssid + " mWifiRssi = " + mWifiRssi + " mWifiLevel = " + mWifiLevel ); List<ScanResult> sameSSIDList = new ArrayList<ScanResult>(); List<ScanResult> list = mWifiManager.getScanResults(); if ( list != null ) { for ( ScanResult rt : list ) { Log.e( TAG, "list ---------- onReceive():ScanResult = " + rt ); if ( curentSSID.equals( rt.SSID ) ) { sameSSIDList.add( rt ); } } } if ( sameSSIDList.size() >= 2 ) { ScanResult strongestRssi = sameSSIDList.get( 0 ); for ( int i = 1; i <= (sameSSIDList.size() - 1); i++ ) { if ( sameSSIDList.get( i ).level > strongestRssi.level ) { strongestRssi = sameSSIDList.get( i ); } } /* * int strongestLevel = WifiManager.calculateSignalLevel( * strongestRssi.level, WifiIcons.WIFI_LEVEL_COUNT); */ Log.e( TAG, "strongestRssi = " + strongestRssi + " mWifiRssi = " + mWifiRssi ); /* if(!currentBssid.equals(strongestRssi.BSSID) && (strongestLevel - mWifiLevel) >= 1){ */ if ( (strongestRssi.level - mWifiRssi) >= 18 ) { Log.e( TAG, "do reconnect now !!!!!!!!!!!!" ); mWifiManager.disconnect(); mWifiManager.reconnect(); isWorking = true; } } } }
逻辑其实很简单,就是根据当前ssid去扫描的列表中找相同ssid的ap如果有,就找信号最强的,当最强的那个信号比当前的信号超过一定的值时,断开重连。当然这种做法还是效率不是高的。原因就是当你在不停的移动中,传过来的信号值其实和当前的实际值有一定的差异。
相关文章推荐
- android虚拟机鼠标左键拖动会输入C
- Android:dp和px之间相互转换
- Android日志存文件实战
- Android控件之ImageView
- LogCat
- Android应用中使用及实现系统“分享”接口
- (转)最强Android模拟器genymotion的安装与配置
- 应用监听自身卸载,弹出用户反馈调查(下)——使用Inotify监听安装目录
- android dumpsys使用
- 实现双击、多击(多次点击)功能
- Android Fragment 真正的完全解析(上)
- Android's matryoshka problem
- Android SlidingDrawer使用
- 应用监听自身卸载,弹出用户反馈调查(上)
- Android自定义控件
- Android——蓝牙连接打印机
- 【Android工具】手机屏幕录制并转换成GIF
- Android Studio Start Failure
- (转)最强Android模拟器genymotion的安装与配置
- Android通过xml自定义圆形ProgressBar的图片