Android中Wi-Fi扫描、连接和信息(一)

1.Wi-Fi介绍

Wi-Fi是一种允许电子设备连接到一个无线局域网(WLAN)的技术,通常使用2.4G UHF或5G SHF ISM 射频频段。连接到无线局域网通常是有密码保护的;但也可是开放的,这样就允许任何在WLAN范围内的设备可以连接上。Wi-Fi是一个无线网络通信技术的品牌,由Wi-Fi联盟所持有。目的是改善基于IEEE 802.11标准的无线网路产品之间的互通性。有人把使用IEEE 802.11系列协议的局域网就称为无线保真。甚至把Wi-Fi等同于无线网际网路(Wi-Fi是WLAN的重要组成部分)。

2.Wi-Fi关键类说明

2.1Wi-Fi相关包说明

做过Wi-Fi开发的人应该都熟悉android.net.wifi包;

android.net.wifi包的简介:

提供在设备上管理Wi-Fi功能的类。

Wi-Fi api提供了一种方式,应用程序可以与提供Wi-Fi网络接入的低层无线栈进行通信。几乎所有来自设备请求者的信息都是可用的,包括连接的网络的链路速度、IP地址、协商状态,以及其他可用的其他网络的信息。其他一些API功能包括扫描、添加、保存、终止和启动Wi-Fi连接。

2.2常用关键类说明

2.2.1WifiManager

WifiManager:这个类提供了管理Wi-Fi连接所有操作的主要API。

定义了许多的常量和方法,查看官网SDK了解;

Wi-Fi连接用到的主要状态,用整型值表示,如下:

Android中Wi-Fi扫描、连接和信息(一)

2.2.2ScanResult

ScanResult:描述探测到的访问点(Wi-Fi)的信息。

ScanResult中关键字段说明:

返回类型 域名 解释
public String BSSID 接入点的地址
public String SSID 网络的名字(在Wi-Fi列表中看的名字)
public String capabilities 网络性能,包括接入点支持的认证、**管理、加密机制等
public int frequency 以MHz为单位的接入频率
public int level 以dBm为单位的信号强度。

2.2.3WifiInfo

WifiInfo:描述已经连接或者活动的Wifi连接状态和信息。

调用WifiInfo类中方法代码:

mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);     
mWifiInfo = mWifiManager.getConnectionInfo();  //获取当前连接Wi-Fi的信息
if(null != mWifiInfo && null != mWifiInfo.getSSID()){  
        String info = "getSSID()="+mWifiInfo.getSSID()+"\n"  
                +"getBSSID()="+mWifiInfo.getBSSID()+"\n"  
                +"getHiddenSSID()="+mWifiInfo.getHiddenSSID()+"\n"  
                +"getLinkSpeed()="+mWifiInfo.getLinkSpeed()+"\n"  
                +"getMacAddress()="+mWifiInfo.getMacAddress()+"\n"  
                +"getNetworkId()="+mWifiInfo.getNetworkId()+"\n"  
                +"getRssi()="+mWifiInfo.getRssi()+"\n"  
                +"getSupplicantState()="+mWifiInfo.getSupplicantState()+"\n"  
                +"getDetailedStateOf()="+mWifiInfo.getDetailedStateOf(mWifiInfo.getSupplicantState());  
        mTVWifiInfo.setText(info);  
}else {  
        mTVWifiInfo.setText("没有连接到wifi");  

2.2.4WifiConfigration

WifiConfigration:一个表示配置的Wi-Fi网络的类,包括安全配置。

 该类主要包含网络配置和安全配置信息,如下:

子类 解释
WifiConfiguration.AuthAlgorthm 获取IEEE 802.11的加密方法
WifiConfiguration.GroupCipher
获取组**
WifiConfiguration.KeyMgmt
获取密码管理体制
WifiConfiguration.PairwiseCipher
获取WPA方式的成对**
WifiConfiguration.Protocol
获取加密协议
WifiConfiguration.Status
获取当前网络状态
更多信息可以查看官方文档;

2.2.5使用Wi-Fi用到的权限

ACCESS_WIFI_STATE:允许应用程序获取Wi-Fi连接的状态;
CHANGE_WIFI_STATE:允许应用程序改变Wi-Fi的连接状态;

CHANGE_WIFI_MULTICAST_STATE:允许改变Wi-Fi组播状态;

具体使用,申请Wi-Fi的操作权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

这块在6.0及以后版本仅添加这两个权限会发现mWifiManager.getScanResults()返回的是空Wi-Fi列表,没有Wi-Fi信息返回;

3.具体实现测试

3.1管理Wi-Fi的关键代码

package com.dress.gold.interconnected.checkphone.utils;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.widget.Toast;

import com.dress.gold.interconnected.checkphone.zxing.decoding.Intents;

import java.util.ArrayList;
import java.util.List;

/**
 * Wi-Fi常见操作类
 * Wi-Fi状态值:One of WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED, WIFI_STATE_ENABLING, WIFI_STATE_UNKNOWN
 */

public class WifiOperator {
    // 定义几种加密方式,一种是WEP,一种是WPA,还有没有密码的情况
    public enum WifiCipherType {
        WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
    }

    //定义管理Wi-Fi连接所有功能类的对象
    private WifiManager mWifiManager;
    //定义存放Wi-Fi信息的对象
    private WifiInfo mWifiInfo;
    //扫描可以访问的Wi-Fi热点的列表
    private List<ScanResult> mWifiList;
    //各个Wi-Fi热点的网络配置的列表
    private List<WifiConfiguration> mWifiConfigration;
    //定义允许应用程序保持Wi-Fi无线电波保持唤醒状态对象
    private WifiManager.WifiLock mWifiLock;

    //构造器
    public WifiOperator(Context context){
        //获取管理Wi-Fi连接所有功能类的对象
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        //返回当前Wi-Fi连接的动态信息,如果有的话。
        mWifiInfo = mWifiManager.getConnectionInfo();
    }

    //打开Wi-Fi
    public void openWifi(Context context){
        //检测打开Wi-Fi功能
        if(!mWifiManager.isWifiEnabled()){
            mWifiManager.setWifiEnabled(true);
        }else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING){
            Toast.makeText(context,"Wi-Fi正在开启中,请勿重复开启", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context,"Wi-Fi已经开启,请勿重复开启", Toast.LENGTH_SHORT).show();
        }
    }

    //关闭Wi-Fi
    public void closeWifi(Context context){
        //检测关闭Wi-Fi功能
        if(mWifiManager.isWifiEnabled()){
            mWifiManager.setWifiEnabled(false);
        }else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING){
            Toast.makeText(context,"Wi-Fi正在关闭中,请勿重复关闭", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context,"Wi-Fi已经关闭,请勿重复关闭", Toast.LENGTH_SHORT).show();
        }
    }

    //检车当前Wi-Fi的状态
    public void checkState(Context context){
        if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING) {
            Toast.makeText(context,"Wifi正在关闭中", Toast.LENGTH_SHORT).show();
        } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
            Toast.makeText(context,"Wifi已经关闭", Toast.LENGTH_SHORT).show();
        } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
            Toast.makeText(context,"Wifi正在开启中", Toast.LENGTH_SHORT).show();
        } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
            Toast.makeText(context,"Wifi已经开启", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context,"没有获取到WiFi状态", Toast.LENGTH_SHORT).show();
        }
    }

    //锁定Wi-FiLock
    public void acquireWifiLock(){
        mWifiLock.acquire();
    }

    //解锁Wi-FiLock
    public void releaseWifiLock(){
        //判断是否还持有锁
        if(mWifiLock.isHeld()){
            mWifiLock.release();
        }
    }

    //创建一个Wi-FiLock
    public void createWifiLock(){
        mWifiLock = mWifiManager.createWifiLock("TAG");
    }

    //得到配置好的网络
    public List<WifiConfiguration> getConfigration() {
        return mWifiConfigration;
    }

    //指定配合找的网络进行连接
    public void connectionConfigration(int index){
        //索引大于配置好的网络索引返回
        if(index>mWifiConfigration.size()){
            return;
        }

        mWifiManager.enableNetwork(mWifiConfigration.get(index).networkId, true);
    }

    public void startScan(Context context) {
        mWifiManager.startScan();
        // 得到扫描结果
        mWifiList = mWifiManager.getScanResults();
        // 得到配置好的网络连接
        mWifiConfigration = mWifiManager.getConfiguredNetworks();
        if (mWifiList == null) {
            if(mWifiManager.getWifiState()==WifiManager.WIFI_STATE_ENABLED){
                Toast.makeText(context,"当前区域没有无线网络", Toast.LENGTH_SHORT).show();
            }else if(mWifiManager.getWifiState()==WifiManager.WIFI_STATE_ENABLING){
                Toast.makeText(context,"WiFi正在开启,请稍后重新点击扫描", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"WiFi没有开启,无法扫描", Toast.LENGTH_SHORT).show();
            }
        }
    }

    //得到网络列表
    public List<ScanResult> getWifiList(){
//        if(mWifiList == null || mWifiList.size() == 0){
//            return mWifiManager.getScanResults();
//        }
        return mWifiList;
    }

    //查看扫描结果
    public StringBuilder lookUpScan(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < mWifiList.size(); i++) {
            sb
                    .append("Index_" + new Integer(i + 1).toString() + ":");
            // 将ScanResult信息转换成一个字符串包
            // 其中把包括:BSSID、SSID、capabilities、frequency、level
            sb.append((mWifiList.get(i)).toString());
            sb.append("/n");
        }
        return sb;
    }

    //添加一个网络并连接
    public void addNetworkWifiConfiguration(WifiConfiguration wc){
        int wcgID = mWifiManager.addNetwork(wc);
        boolean b = mWifiManager.enableNetwork(wcgID, true);
        Log.i(WifiOperator.class.getName(), "wcgID:"+wcgID);
        Log.i(WifiOperator.class.getName(), "b:"+b);
    }

    //断开指定ID网络
    public void disconnectWifi(int netId){
        mWifiManager.disableNetwork(netId);
        mWifiManager.disconnect();
    }

    public void removeWifi(int netId){
        disconnectWifi(netId);
        mWifiManager.removeNetwork(netId);
    }

    public WifiConfiguration createWifiInfo(String SSID, String password, WifiCipherType type){
        WifiConfiguration configuration = new WifiConfiguration();
        configuration.allowedAuthAlgorithms.clear();
        configuration.allowedGroupCiphers.clear();
        configuration.allowedKeyManagement.clear();
        configuration.allowedPairwiseCiphers.clear();
        configuration.allowedProtocols.clear();
        configuration.SSID = "\"" + SSID + "\"";

        WifiConfiguration tempConfiguration = this.isExists(SSID);
        if(tempConfiguration != null){
            mWifiManager.removeNetwork(tempConfiguration.networkId);
        }

        if(type == WifiCipherType.WIFICIPHER_NOPASS){
            configuration.wepKeys[0] = "";
            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            configuration.wepTxKeyIndex = 0;
        }

        if(type == WifiCipherType.WIFICIPHER_WEP){
            configuration.hiddenSSID = true;
            configuration.wepKeys[0] = "\""+password+"\"";
            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            configuration.wepTxKeyIndex = 0;
        }
        if(type == WifiCipherType.WIFICIPHER_WPA){
            configuration.preSharedKey = "\""+password+"\"";
            configuration.hiddenSSID = true;
            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            //config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            configuration.status = WifiConfiguration.Status.ENABLED;
        }

        return configuration;
    }

    //判断某个Wi-Fi是否存在
    private WifiConfiguration isExists(String SSID){
        List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
        for(WifiConfiguration existingConfig : existingConfigs){
            if(existingConfig.SSID.equals("\""+SSID+"\"")){
                return existingConfig;
            }
        }

        return null;
    }

    // 得到MAC地址
    public String getMacAddress() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
    }

    // 得到接入点的BSSID
    public String getBSSID() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
    }

    // 得到IP地址
    public int getIPAddress() {
        return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
    }

    // 得到连接的ID
    public int getNetworkId() {
        return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
    }

    // 得到WifiInfo的所有信息包
    public String getWifiInfo() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();
    }
}

3.2通过调用上面的方法会发现一些问题,如下图

Android中Wi-Fi扫描、连接和信息(一)

1.问题1,SSID有获取不到的情况,即SSID为空串"",SSID!=null的情况;

2.问题2,wifi列表中有许多同名的wifi热点,也就是扫描的结果中有重合部分,并不是有多个同名的wifi热点;

问题1的原因:第一个问题ssid为空串,这个看设置中并没有多余wifi,但这个热点点其它信息可以获取到,说明这个热点是存在的,应该是该热点隐藏了,所以获取不到。这也就是手机设置中为什么会有添加网路的按钮了。

问题2的原因:当附近wifi热点比较少时不会出现此问题,当附近wifi网络比较多时会出现此问题。这就需要将同名的热点进行删除,但是如果真有两个ssid名相同的wifi,那就可以通过capabilities去区分吧,如果capabilities也相同就没办法了,系统设置里面也不显示同名的;

因此扫描代码需要做一些调整,调整如下:

//扫描Wi-Fi列表
    public void startScan(Context context){
        //启动Wi-Fi扫描
        mWifiManager.startScan();
        //得到Wi-Fi热点扫描结果列表
        List<ScanResult> results = mWifiManager.getScanResults();
        //得到配置好的网络连接
        mWifiConfigration = mWifiManager.getConfiguredNetworks();

        if(results == null){
            if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED){
                Toast.makeText(context,"当前区域没有扫描到无线Wi-Fi网络", Toast.LENGTH_SHORT).show();
            }else if(mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING){
                Toast.makeText(context,"Wi-Fi正在开启中,请稍后重新扫描", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"Wi-Fi没有开启,暂时无法扫描,请打开Wi-Fi以后点击扫描", Toast.LENGTH_SHORT).show();
            }
        }else{
//            Toast.makeText(context,"当前可连接Wi-Fi数量:"+mWifiList.size(), Toast.LENGTH_SHORT).show();
            //过滤掉重复Wi-Fi名称
            mWifiList = new ArrayList();
            for(ScanResult result : results){
                if (result.SSID == null || result.SSID.length() == 0 || result.capabilities.contains("[IBSS]")) {
                    continue;
                }
                boolean found = false;
                for(ScanResult item:mWifiList){
                    if(item.SSID.equals(result.SSID)&&item.capabilities.equals(result.capabilities)){
                        found = true;break;
                    }
                }
                if(!found){
                    mWifiList.add(result);
                }
            }
        }
    }

修改后的效果:

Android中Wi-Fi扫描、连接和信息(一)

3.2调用Wi-Fi工具类的代码

package com.dress.gold.interconnected.checkphone.ui.testui;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.dress.gold.interconnected.checkphone.R;
import com.dress.gold.interconnected.checkphone.base.ToolbarActivity;
import com.dress.gold.interconnected.checkphone.ui.MainActivity;
import com.dress.gold.interconnected.checkphone.utils.WifiOperator;

import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * 测试Wi-Fi管理功能
 */

public class WifiOperatorActivity extends ToolbarActivity {

    private WifiOperator mwifiOperator;
    private List<ScanResult> mWifiList;
    @Bind(R.id.wifilistView)
    ListView wifilistView;

    public int level;
    protected String ssid;

    @Override
    protected int provideContentViewId() {
        return R.layout.activity_wifi;
    }

    @Override
    public boolean canBack() {
        return false;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ButterKnife.bind(this);

        mwifiOperator = new WifiOperator(this);
        addWifiConnectionListener();

        addListViewClick();
    }

    private void addListViewClick() {
        wifilistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                AlertDialog.Builder alert=new AlertDialog.Builder(WifiOperatorActivity.this);
                ssid=mWifiList.get(position).SSID;
                alert.setTitle(ssid);
//                alert.setMessage("输入密码");
                final TextView tv = new TextView(WifiOperatorActivity.this);
//                ScanResult scanResult = mWifiList.get(position);
//                tv.setText("SSID:"+scanResult.SSID+"\n"
//                        +"BSSID:"+scanResult.BSSID+"\n"
//                        +"capabilities:"+scanResult.capabilities+"\n"
//                        +"frequency:"+scanResult.frequency+"\n"
//                        +"level:"+scanResult.level+"\n");
//                alert.setView(tv);
                final EditText et_password=new EditText(WifiOperatorActivity.this);
                final SharedPreferences preferences=getSharedPreferences("wifi_password",Context.MODE_PRIVATE);
                et_password.setText(preferences.getString(ssid, ""));
                alert.setView(et_password);
                //alert.setView(view1);
                alert.setPositiveButton("连接", new DialogInterface.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String pw = et_password.getText().toString();
                        if(null == pw  || pw.length() < 8){
                            Toast.makeText(WifiOperatorActivity.this, "密码至少8位", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        SharedPreferences.Editor editor=preferences.edit();
                        editor.putString(ssid, pw);   //保存密码
                        editor.commit();
                        mwifiOperator.addNetworkWifiConfiguration(mwifiOperator.createWifiInfo(ssid, et_password.getText().toString(), WifiOperator.WifiCipherType.WIFICIPHER_WPA));
                    }
                });
                alert.setNegativeButton("取消", new DialogInterface.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //
                        //mWifiAdmin.removeWifi(mWifiAdmin.getNetworkId());
                    }
                });
                alert.create();
                alert.show();

            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }

    public void addWifiConnectionListener(){
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        //="android.net.wifi.STATE_CHANGE"  监听wifi状态的变化
        registerReceiver(mReceiver, filter);
    }

    @OnClick({R.id.detectstatus, R.id.openwifi, R.id.closewifi, R.id.scanwifi})
    public void onClick(Button button){
        switch (button.getId()){
            case R.id.detectstatus:
                mwifiOperator.checkState(this);
                break;
            case R.id.openwifi:
                mwifiOperator.openWifi(this);
                break;
            case R.id.closewifi:
                mwifiOperator.closeWifi(this);
                break;
            case R.id.scanwifi:
                mwifiOperator.startScan(this);
                mWifiList = mwifiOperator.getWifiList();
                if(mWifiList != null){
                    wifilistView.setAdapter(new MyAdapter(this,mWifiList));
                }
                break;
        }
    }

    public class MyAdapter extends BaseAdapter {
        LayoutInflater inflater;
        List<ScanResult> list;
        public MyAdapter(Context context, List<ScanResult> list){
            this.inflater=LayoutInflater.from(context);
            this.list=list;
        }
        @Override
        public int getCount() {
            return list.size();
        }
        @Override
        public Object getItem(int position) {
            return position;
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @SuppressLint({ "ViewHolder", "InflateParams" })
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view=null;
            view=inflater.inflate(R.layout.wifi_listitem, null);
            ScanResult scanResult = list.get(position);
            TextView wifi_ssid=(TextView) view.findViewById(R.id.ssid);
//            ImageView wifi_level=(ImageView) view.findViewById(R.id.wifi_level);
            wifi_ssid.setText(scanResult.SSID+"("+scanResult.capabilities+")");
//            Log.i(TAG, "scanResult.SSID="+scanResult);
//            level= WifiManager.calculateSignalLevel(scanResult.level,5);
//            if(scanResult.capabilities.contains("WEP")||scanResult.capabilities.contains("PSK")||
//                    scanResult.capabilities.contains("EAP")){
//                wifi_level.setImageResource(R.drawable.wifi_signal_lock);
//            }else{
//                wifi_level.setImageResource(R.drawable.wifi_signal_open);
//            }
//            wifi_level.setImageLevel(level);
            //判断信号强度,显示对应的指示图标
            return view;
        }
    }

    //监听wifi状态
    private BroadcastReceiver mReceiver = new BroadcastReceiver(){
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            // wifi已成功扫描到可用wifi。
            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                Toast.makeText(context, "Wi-Fi已成功扫描到可用wifi", Toast.LENGTH_LONG).show();
                //mwifiOperator.startScan(WifiOperatorActivity.this);
                mWifiList = mwifiOperator.getWifiList();
                if(mWifiList != null){
                    wifilistView.setAdapter(new MyAdapter(WifiOperatorActivity.this,mWifiList));
                }

//                Toast.makeText(context,"当前可连接Wi-Fi数量:"+mWifiList.size(), Toast.LENGTH_SHORT).show();
            }//系统wifi的状态
            else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                Toast.makeText(context, "Wi-Fi状态有变化", Toast.LENGTH_LONG).show();
                ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

                NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                if(wifiInfo.isConnected()){
                    WifiManager wifiManager = (WifiManager) context
                            .getSystemService(Context.WIFI_SERVICE);
                    String wifiSSID = wifiManager.getConnectionInfo()
                            .getSSID();
                    Toast.makeText(context, wifiSSID+"连接成功", Toast.LENGTH_LONG).show();
                }
            }
        }
    };
}

具体注意事项:

在注册监听Wi-Fi相关信息广播时,主要添加两个Action,一个是监听扫描附近Wi-Fi的Action:

SCAN_RESULTS_AVAILABLE_ACTION,另一个是时监听Wi-Fi状态(Wi-Fi关闭,打开,连接成功)变化的Action

filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

调用mWifiManager.getScanResults();方法时一直获取不到附近的Wi-Fi列表,可以通过源代码发现逻辑判断中需要打开定位功能;

试了一最笨的方法,添加定位权限,如下:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

发现添加这两个权限以后还是获取不到附近的Wi-Fi列表,我手动打开定位功能,重新扫描获取可以得到,当然这种办法还是比较low的;

这篇文章分析了为什么需要打开定位的可以查看一下:

https://www.jianshu.com/p/3400ca0deeee

代码中做一下修改即可:

加入上面两个权限的同时,动态打开定位而不是人为手动打开定位即可:

if (Build.VERSION.SDK_INT >= 23 && 
!AppUtil.isGpsOPen(this)) {
     Settings.Secure.putInt(getContentResolver(),Settings.Secure.LOCATION_MODE, 1);
}

4.其他说明

参考:

https://blog.****.net/vnanyesheshou/article/details/50771698

https://developer.android.google.cn/reference/android/net/wifi/package-summary

测试代码:

https://download.****.net/download/ahou2468/10401108