Android修真传之WIFI的使用
本人是个刚满一年经验的小新,正在进行Android修仙之路,由于没有师傅只能单兵作战,在修仙过程之中不断通过实战提高自己的修为。若对实战过程中有误的地方希望道友帮忙指正,不然本人将误入歧途最终成魔(哈哈)。在实战过程之前小辈会参考其他前辈的实战经验,这也是大多修真者都会这么做的,所以在实战过程中都不是原创。
前言
WIFI在普通应用中并不常用,如果是在跟嵌入式产品通信的话这个就比较常用,在和嵌入式产品通信的时候我们往往可以选择蓝牙和WIFI,但是大部分都选择蓝牙,应为蓝牙他的功耗比较低,缺点就是传输距离短,WIFI的话就和蓝牙相反。如果玩过大疆无人机的话应该知道大疆的遥控以及手机软件都是使用WIFI,应为他传输距离长,下面是简单的对比,可以忽略ZigBee。 蓝牙WIFI对比WIFI所需要的权限
<!-- wifi控制和状态权限 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 网络状态改变的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 6.0以上打开蓝牙和wifi最好加上定位权限,获取wifi列表要用 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>
WIFI操作步骤
在使用WIFI前首先给获取WifiManager 对象,这个对象提供用于管理Wi-Fi连接的所有方面的主要API,可以查看和更新列表,并且可以修改各个条目的属性。可以建立或拆除连接,并且可以查询关于网络状态的动态信息。
WifiManager mWifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if(mWifiManager == null){
Log.d(TAG,"该设备不支持WIFI");
MainActivity.this.finish();
}
当获取到WifiManager 之后就可以打开和关闭WIFI
/**
* 打开当前WIFI
*/
public void openWifi() {
//WIFI是否已经打开
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
}
/**
* 关闭当前WIFI
*/
public void closeWifi() {
if (mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(false);
}
}
WIFI被打开后我们需要进行扫描来获取周边的WIFI设备。
/**
* 开始扫描
*/
public void startScanWifi(){
if(!mWifiManager.isWifiEnabled()){
return;
}
mWifiManager.startScan();
}
注意:Android 8.0(API级别26)引入了有关权限和Wi-Fi扫描允许频率的限制。为了提高网络性能,安全性和电池寿命,Android 9(API级别28)收紧了权限要求,并进一步限制了Wi-Fi扫描的频率。当该系统版本为8.0或者8.1的时候每个后台应用程序可以在30分钟内扫描一次。当该系统版本在9.0以上的时候每个前台应用程序可以在2分钟内扫描四次。这允许在短时间内进行扫描。当我们调用startScan()方法的时候需要确保拥有上面列出权限,否则不能正常调用。
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(WifiScanReceiver, intentFilter);
BroadcastReceiver WifiScanReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent intent) {
if(intent.getAction().endsWith(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
boolean success = intent.getBooleanExtra(
WifiManager.EXTRA_RESULTS_UPDATED, false);
if (success) {
showToast("WIFI扫描完成");
List<ScanResult> scanResultList = mWifiManager.getScanResults();
} else {
showToast("WIFI扫描失败");
}
}
}
};
扫描完成的时候系统会发出广播,所以我们需要先注册广播后判断扫描的状态,当扫描成功的时候就可以调用mWifiManager.getScanResults()方法获取扫描结果,如果当前扫描尚未完成或成功,则可能来自先前的扫描结果。这意味着如果在接收成功的SCAN_RESULTS_AVAILABLE_ACTION广播之前调用此方法,则可能会获得较旧的扫描结果 。注意:要成功调用WifiManager.getScanResults(),请确保满足以下所有条件:
- 您的应用具有ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限。
- 您的应用具有ACCESS_WIFI_STATE权限。
- 设备上启用了位置服务(在“设置”>“位置”下)。
如果调用应用程序不满足所有这些要求,则调用将失败并显示SecurityException。
上面mWifiManager.getScanResults()获取的是一个装着ScanResult对象的集合,那么这个ScanResult是什么呢?
ScanResultScanResult这个类主要是通过Wifi硬件的扫描来获取一些周边的wifi热点(access point)的信息,下面列出该对象常用的属性。