基于Android 6.0获取指定Mac地址WiFi信息


  • 基于Android 60获取指定Mac地址WiFi信息
  • ScanResult类
  • 实现步骤
  • 权限申请
  • 获取WiFi列表并匹配指定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"/>

以上。