基于Android 6.0获取指定Mac地址WiFi信息
上一篇介绍了获取当前连接WiFi信息的方法。而由于WiFi路由器可能通过增大功率以维持WiFi信号强度,导致我们基于WiFi信号强度(RSSI)计算手机终端与热点之间的距离不准确。所以我们采用不连接此WiFi,通过扫描周边WiFi获取WiFi列表,进而从中找到指定Mac地址的WiFi信息。
ScanResult类
这个类主要是通过Wifi硬件的扫描来获取一些周边的wifi热点(access point)的信息。该类主要有5个域:
返回类型 | 域名 | 解释 |
---|---|---|
public String | BSSID | 接入点的地址 |
public String | SSID | 网络的名字 |
public String | capabilities | 网络性能,包括接入点支持的认证、密钥管理、加密机制等 |
public int | frequency | 以MHz为单位的接入频率 |
public int | level | 以dBm为单位的信号强度 |
实现步骤
权限申请
不要忘记后面两个的权限。
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
获取WiFi列表并匹配指定Mac地址WiFi
import略。
public class MainActivity extends Activity {
public WifiManager wifiManager;
public ConnectivityManager connectManager;
public NetworkInfo netInfo;
public WifiInfo wifiInfo;
public DhcpInfo dhcpInfo;
List<android.net.wifi.ScanResult> list;
TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.tv1);
new Thread(){
@Override
public void run() {
while (true) {
SystemClock.sleep(1000);
wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
connectManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
netInfo = connectManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
wifiInfo = wifiManager.getConnectionInfo();
wifiManager.startScan();//扫描
list = wifiManager.getScanResults();//返回的扫描结果
logg(list); //打印出列表的内容
//热点123cba的mac地址为 50:bd:5f:19:75:59
//获取扫描到的wifi的 mac地址
//字符串匹配指定的 mac地址
//如果匹配成功则获取并显示该wifi信号强度计算距离和名字
String wifiProperty="wifi not found";
for(ScanResult result:list){
//进行Mac地址匹配
if("50:bd:5f:19:75:59".equals(result.BSSID)){
wifiProperty = "当前匹配WIFI信息如下:" + result.SSID + '\n' +
"mac:" + result.BSSID+ '\n' +
"rssi:" + result.level + '\n' +
DisByRssi(result.level);
Log.i("he", wifiProperty);
break;
}
}
final String ss=wifiProperty;
runOnUiThread(new Runnable() {
@Override
public void run() {
tv1.setText(ss);
}
});
}
}
//距离计算函数
public Double DisByRssi(int rssi){
int iRssi = Math.abs(rssi);
double power = (iRssi- 35)/(10*2.1);
return Math.pow(10,power);
}
}.start();
}
//Log打印函数
public void logg(List<android.net.wifi.ScanResult> resultList){
Log.d("resultlist","log result list");
for(ScanResult result:resultList){
Log.d("resultlist","ssid: "+result.SSID+" Bssid: "+result.BSSID);
}
}
}
xml文件为一个简单的Text View。
遇到的问题
在程序运行之初并没有得到指定Mac地址WiFi的信息,通过打印Log发现原来是getScanResults返回了一个空表。
那么是什么原因呢?我们查看Android6.0 getScanResults的源码发现了原因:
if (!canReadPeerMacAddresses && !isActiveNetworkScorer&& !isLocationEnabled())
{
return new ArrayList<ScanResult>();
}
可以看到如果定位关闭,那么将直接返回一个空的列表。Android6.0以上的系统在扫描WiFi时需要让用户去打开GPS。当我打开定位开关时成功返回了WiFi列表。
当然这也是需要权限的,也就是我在最开始提醒大家不要落下的:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
以上。