A. android的WiFi功能总结
先进行WiFi权限的声明
<!-- 获取WiFi状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- api <= Android29调用setWifiEnabled -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 定位权限(api >= 23 用于 WIFI扫描)-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
注意:ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION是危险级权限需要使用中还需要动态申请,申请其中一个即可。
WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.R) {
Intent panelIntent =new Intent(Settings.Panel.ACTION_WIFI);
startActivityForResult(panelIntent,null);
}else{ mWifiManager.setWifiEnabled(!isEnable);}
可以通过监听系统广播来了解WiFi状态。
WIFI_STATE_CHANGED_ACTION:WiFi开关状态;
SCAN_RESULTS_AVAILABLE_ACTION:WiFi列表变化;
RSSI_CHANGED_ACTION:WiFi信号强度变化。
IntentFilter mFilter =new IntentFilter();
mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
mReceiver =new BroadcastReceiver() {
@Override
public void onReceive(Context context,Intent intent) {
handleEvent(intent);
}
};
registerReceiver(mReceiver, mFilter);
private void handleEvent(Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
final int wifiState =mWifiManager.getWifiState();
if(wifiState ==WifiManager.WIFI_STATE_ENABLED){
postDelayed(()->{mRefreshLayout.autoRefresh();},1000);
}
}else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
}else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
if(System.currentTimeMillis() -mLastUpateWifiRssiTime <1000){//刷新太快
return;
}
}
updateWifiChange();
}
切记:wifistate切换到WifiManager.WIFI_STATE_ENABLED,mWifiManager.isWifiEnabled()需要有个等待时间切换。
3的基础上解析广播应答
private void updateWifiChange() {
final int wifiState =mWifiManager.getWifiState();
switch (wifiState) {
case WifiManager.WIFI_STATE_ENABLED:
ArrayListresults = (ArrayList)mWifiManager.getScanResults();
updateApListView(results);
mWlanSb.setChecked(mWifiManager.isWifiEnabled() );
break;
case WifiManager.WIFI_STATE_ENABLING:
break;
case WifiManager.WIFI_STATE_DISABLING:
mAdapter.clearData();
mWlanSb.setChecked(mWifiManager.isWifiEnabled() );
break;
case WifiManager.WIFI_STATE_DISABLED:
break;
}
}
B. 淫技:android无屏操作之adb操控wifi
1.开启wpa_supplicant服务端
meta_wpa_supplicant.conf是配置文件,ctrl_interface是wpa_supplicant与wpa_cli通信的接口,ssid为要连接的wifi热点名称,key_mgmt为加密方式(NONE表示不加密 O(∩_∩)O~)。
2.wpa_cli连接wpa_supplicant
3.扫描wifi
4.使能network0
上面都是完整的语句,我们可以直接使用/system/bin/wpa_cli -iwlan0 -p /data/misc/wifi/sockets进入wifi命令模式,如下图所示,wifi命令模式下可以直接使用scan,status等指令
成功连上了TE-NonSignal的wifi,你可能会纳闷,怎么执行enable_network 0就连上了呢?手机怎么知道network 0是什么鬼呢?上面说了有个配置文件meta_wpa_supplicant.conf,有了这个配置文件就会自动连接TE-NonSignal网络了。
上面是使用配置文件去连接网络,当然我们也可以用命令行去连接网络啦
执行scan
然后执行scan_result,下图为扫描结果
例如我们要连个公共网络OPPO-SZ,首先我们执行
add_network 如下图返回4,说明接下来要连接的network的id为4
依次执行
set_network 4 ssid "OPPO-SZ"
set_network 4 key_mgmt NONE
enable_network 4
如下图,说明成功连接上wifi了
C. Android WiFi扫描
Wifi scanning overview
必须权限如下:
除必须权限外,根据系统版本,还有不同的限制。具体如下
WifiManager.getScanResults() 方法的调用必须具备以下 任一 权限:
否则会抛异常 SecurityException 。
WifiManager.startScan() 方法的调用必须满足以下 所有 条件:
否则会抛异常 SecurityException 。
Android对 WifiManager.startScan() 的调用频率进行了限制。对于超过此频率的接口访问, WifiManager 不会执行完整扫描,而是提供上次扫描所缓存的结果。
平均值:2211
wifi扫描有两个必须权限:
另外,随着Android系统的升级,对WiFi扫描做了越来越严格的限制。系统对 WifiManager.getScanResults() 和 WifiManager.startScan() 所做的限制不太一样,但若要实现一个完整的WiFi扫描,就需要“扫描+获取”两个步骤,因此综合来看,WiFi扫描的行为变化如下:
需要同时满足以下所有条件:
<font color='red'>注意:以上是官方文档的说明,与实际测试的结果有出入,可能是手机厂商修改rom导致。</font>
(小米MIX2 8.0,三星N9600 8.1.0下,不开定位服务也能获取到WiFi列表)
D. android开发怎么判断wifi信号强度
通过WifiManager的方法getScanResults()获取List<ScanResult>的集合,ScanResult.level就是信号强度是个负数,然后使用
WifiManager.calculateSignalLevel(scanResult.level,
100);就可得到确定的信号强度(calculateSignalLevel为计算信号等级函数,MAX_RSSI和MIN_RSSI分别为最强和最弱信号强度等级的信号强度阀值)。