美文网首页
Android Wifi相关操作

Android Wifi相关操作

作者: 风吹尘埃 | 来源:发表于2020-09-01 17:22 被阅读0次

Android WIFI

参考链接

概念

相关权限

权限 说明 动态申请
android.permission.ACCESS_WIFI_STATE 获取wifi状态
android.permission.CHANGE_WIFI_STATE 更改wifi状态
android.permission.ACCESS_FINE_LOCATION 精确定位(用于8.0以上扫描wifi)

相关类

类名 说明
WifiManager Wifi统一管理类,执行wifi相关操作 WifiInfo:描述当前wifi信息
WifiInfo 描述当前wifi信息
WifiConfiguration wifi网络配置信息
ScanResult 获取附近wifi时返回的wifi热点信息

相关术语

名称 功能
SSID / ESSID 描述热点的名称
BSSID 热点的MAC地址
networkID 数字型id
RSSI / level wifi信号强弱等级

wifi的广播

  • 开启广播监听
 IntentFilter filter = new IntentFilter();
 if (Build.VERSION.SDK_INT >= 28) {
  filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
 }
 // Android 8.0之后对静态注册的广播增加限制,保护用户隐私,故推荐使用动态注册
 // WifiStateBroadcast 继承自 BroadcastReceiver
 filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
 filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
 registerReceiver(new WifiStateBroadcast(), filter);</pre>
  • 对收到的广播区分
    • wifi状态变化会发出以下广播
类型 说明
WifiManager.WIFI_STATE_CHANGED_ACTION wifi开关变化通知
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION wifi扫描结果通知
WifiManager.SUPPLICANT_STATE_CHANGED_ACTION wifi连接结果通知
WifiManager.NETWORK_STATE_CHANGED_ACTION 网络状态变化通知
public class WifiStateBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        switch (action){
            case WifiManager.WIFI_STATE_CHANGED_ACTION:
                Log.d("打印", "onReceive: wifi开关变化通知");
                break;
            case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
                Log.d("打印", "onReceive: 扫描wifi结果通知");
                break;
            case WifiManager.SUPPLICANT_STATE_CHANGED_ACTION:
                Log.d("打印", "onReceive: wifi连接结果通知");
                break;
            case WifiManager.NETWORK_STATE_CHANGED_ACTION:
                Log.d("打印", "onReceive: 网络状态变化");
                break;
            case LocationManager.PROVIDERS_CHANGED_ACTION:
                Log.d("打印", "onReceive: 定位变化通知");
                break;
        }

    }
}

Wifi的操作

开启或关闭wifi

WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 开启或关闭wifi  对于Android 10.0及以上已经禁用
boolean isOpen = wifiManager.setWifiEnabled(true);
// 获取 Wifi 开关的状态
boolean isEnable = wifiManager.isWifiEnabled();

获取wifi状态

状态 说明
WIFI_STATE_DISABLING 0 wifi关闭中,如果完成,那么会切换到 WIFI_STATE_DISABLED
WIFI_STATE_DISABLED 1 wifi已关闭
WIFI_STATE_ENABLING 2 wifi开启中,如果完成,那么会切换到 WIFI_STATE_ENABLED
WIFI_STATE_ENABLED 3 wifi已开启
WIFI_STATE_UNKNOWN 4 未知状态
// 获取wifi状态
 int wifiState = wifiManager.getWifiState();

获取当前wifi信息

WifiInfo connectionInfo = wifiManager.getConnectionInfo();
String ssid = connectionInfo.getSSID();// 获取ssid
int ipAddress = connectionInfo.getIpAddress(); // ip的整数形式,需要转换成String形式
String bssid = connectionInfo.getBSSID(); // bssid
int rssi = connectionInfo.getRssi(); // rssi
int networkId = connectionInfo.getNetworkId(); // networkId

将 IP 转String形式

private static String formatIp(int ip){
    String ipAddr = (ip & 0xFF) + "." +
        ((ip >> 8) & 0xFF) + "." +
        ((ip >> 16) & 0xFF) + "." +
        (ip >> 24 & 0xFF);
    return ipAddr;
}

扫描附近wifi

Google: startScan() This method was deprecated in API level P. The ability for apps to trigger scan requests will be removed in a future release.
翻译:
startScan() 在API级别P中已弃用此方法。在将来的版本中,将删除应用程序触发扫描请求的功能。

目前 Android 10 版本手机需要动态申请 ACCESS_COARSE_LOCATION 权限才能获取扫描结果
前台应用两分钟只能扫描4次,4次之后会返回最后一次扫描的结果
后台应用三十分钟(未试验)只能扫描1次,1次之后会返回最后一次扫描的结果

// 动态申请权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />    
boolean isScanSuccess = wifiManager.startScan(); // 开始扫描,成功返回true
// 结果会异步返回到注册的广播中
public class WifiStateBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
            WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            List<ScanResult> scanResults = wifiManager.getScanResults();
            for (int i = 0; i < scanResults.size(); i++) {
                ScanResult scanResult = scanResults.get(i);
                String ssid = scanResult.SSID; // SSID
                int level = scanResult.level; // 信号强弱
                String bssid = scanResult.BSSID; // BSSID
                String capabilities = scanResult.capabilities; // 加密方式:WPA/WPA2,WPA,WPA2,WEP,空(不加密)
            }
        }
    }
}

连接wifi

  • 未连接过的wifi
/**
 * ssid: 要连接的ssid
 * password: 要连接的密码
 * encryptType: 加密方式
 */
public static void connectWifi (Context context, String ssid, String password, int encryptType) {

    if (!getWifiEnabled()){
        return;
    }

    WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    WifiConfiguration wc = new WifiConfiguration();
    wc.allowedAuthAlgorithms.clear();
    wc.allowedGroupCiphers.clear();
    wc.allowedKeyManagement.clear();
    wc.allowedPairwiseCiphers.clear();
    wc.allowedProtocols.clear();
    wc.SSID = "\"" + ssid + "\"";

    WifiConfiguration configuration = getWifiConfig(context, ssid);
    if (configuration != null) {
        wm.removeNetwork(configuration.networkId);
    }
    switch (encryptType) {
        case 4:
            // 不加密
            wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            break;
        case 3:
            //wep 加密
            wc.hiddenSSID = true;
            wc.wepKeys[0] = "\"" + password +"\"";
            wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            break;
        case 0:
            // wpa/wap2加密
        case 1:
            // wpa2加密
        case 2:
            // wpa加密
            wc.preSharedKey = "\"" + password + "\"";
            wc.hiddenSSID = true;
            wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            wc.status = WifiConfiguration.Status.ENABLED;
            break;
        default:
            break;
    }
    // 如果 network = -1,那么这个wifi是已经连接过的
    int network = wm.addNetwork(wc);
    if (network == -1){
        connectWifi(context,ssid);
    }else {
        wm.disconnect();
        wm.enableNetwork(network, true);
    }
}
  • 连接过的wifi
public static void connectWifi (Context context, String ssid) {
    WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    WifiConfiguration wc = new WifiConfiguration();
    wc.SSID = "\"" + ssid + "\"";
    WifiConfiguration configuration = getWifiConfig(context, ssid);
    if (configuration != null) {
        wm.disconnect();
        wm.enableNetwork(configuration.networkId, true);
    }

}

工具类

/**
 * wifi操作工具类
 * 来源: 网络
 */
public class WifiUtils {
    /**
     * 判断wifi是否打开
     * 需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean getWifiEnabled() {
        @SuppressLint("WifiManagerLeak")
        WifiManager wifiManager = (WifiManager) App.getContext().getSystemService(Context.WIFI_SERVICE);
        return wifiManager.isWifiEnabled();
    }


    public static String getWifiIp(Context context){
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        return (ipAddress & 0xFF) + "." +
                ((ipAddress >> 8) & 0xFF) + "." +
                ((ipAddress >> 16) & 0xFF) + "." +
                (ipAddress >> 24 & 0xFF);
    }

    /**
     * @des 清除wifi配置信息
     * @param context
     * @param ssid
     */
    public static void clearWifiInfo(Context context, String ssid) {

        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        String newSSID = "\"" + ssid + "\"";
        if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
            newSSID = "\"" + ssid + "\"";
        } else {
            newSSID = ssid;
        }

        WifiConfiguration configuration = getWifiConfig(context, newSSID);
        configuration.allowedAuthAlgorithms.clear();
        configuration.allowedGroupCiphers.clear();
        configuration.allowedKeyManagement.clear();
        configuration.allowedPairwiseCiphers.clear();
        configuration.allowedProtocols.clear();

        if (configuration != null) {

            wm.removeNetwork(configuration.networkId);
            wm.saveConfiguration();
        }
    }

    public static WifiConfiguration getWifiConfig (Context context, String ssid) {

        if (TextUtils.isEmpty(ssid)){
            return null;
        }
        String newSSID;
        if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
            newSSID = "\"" + ssid + "\"";
        } else {
            newSSID = ssid;
        }
        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        List<WifiConfiguration> configuredNetworks = wm.getConfiguredNetworks();

        for (WifiConfiguration configuration : configuredNetworks) {
            if (newSSID.equalsIgnoreCase(configuration.SSID)) {
                return configuration;
            }
        }

        return null;
    }

    /**
     * Wifi加锁方式
     * @param capabilities
     * @return
     */
    public static int getWifiLockType(String capabilities){
        if (TextUtils.isEmpty(capabilities)) {
            return -1;
        }
        int encryptType;

        if (capabilities.contains("WPA") && capabilities.contains("WPA2")) {
            encryptType = 0;
        } else if (capabilities.contains("WPA2")) {
            encryptType = 1;
        } else if (capabilities.contains("WPA")) {
            encryptType = 2;
        } else if (capabilities.contains("WEP")) {
            encryptType = 3;
        } else {
            encryptType = 4;
        }

        return encryptType;
    }

    /**
     *
     * 获取WIFI列表
     * <p>需要权限{@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>}</p>
     * <p>注意Android6.0上需要主动申请定位权限,并且打开定位开关</p>
     *
     * @param context 上下文
     * @return wifi列表
     */
    public static List<ScanResult> getWifiList(Context context) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        List<ScanResult> scanResults = wm.getScanResults();
        WifiInfo info = wm.getConnectionInfo();

        List<ScanResult> nlist = new ArrayList<>();
        for (int i = 0; i < scanResults.size(); i++) {
            if (scanResults.get(i).SSID.isEmpty()){
                continue;
            }
            if (info != null && info.getSSID() != null && scanResults.get(i).BSSID.equals(info.getBSSID())) {
                // 当前已连接设备不显示在列表中
                continue;
            }

            if (scanResults.get(i).SSID.contains("0460")){
                continue;
            }

            // 该热点SSID是否已在列表中
            int position = getItemPosition(nlist, scanResults.get(i));
            if (position != -1) {
                // 已在列表
                // 相同SSID热点,取信号强的
                if (nlist.get(position).level < scanResults.get(i).level) {
                    nlist.remove(position);
                    nlist.add(position, scanResults.get(i));
                }
            } else {
                nlist.add(scanResults.get(i));
            }
        }


        Collections.sort(nlist, new Comparator<ScanResult>() {
            @Override
            public int compare(ScanResult scanResult1, ScanResult scanResult2) {
                return scanResult2.level - scanResult1.level;
            }
        });
        return nlist;
    }
    /**
     * 返回item在list中的坐标
     */
    private static int getItemPosition(List<ScanResult>list, ScanResult item) {
        for (int i = 0; i < list.size(); i++) {
            if (item.SSID.equals(list.get(i).SSID)) {
                return i;
            }
        }
        return -1;
    }


    public static boolean disconnect(Context context){
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        return wm.disconnect();
    }

    /**
     * 获取当前链接的WiFi信息
     *
     * @param context 上下文
     * @return 当前wifi数据
     */
    public static WifiInfo getCurrentWifi (Context context) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        return wm.getConnectionInfo();
    }


    public static String getWifiEncryptTypeStr (String capabilitie) {
        if (TextUtils.isEmpty(capabilitie)) {
            return null;
        }

        String encryptType;

        if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
            encryptType = "WPA/WPA2 PSK";
        } else if (capabilitie.contains("WPA2")) {
            encryptType = "WPA2 PSK";
        } else if (capabilitie.contains("WPA")) {
            encryptType = "WPA PSK";
        } else if (capabilitie.contains("WEP")) {
            encryptType = "WEP";
        } else {
            encryptType = "NONE";
        }

        return encryptType;
    }

    /**
     * wifi加密方式有5种
     * 0 - WPA/WPA2 PSK
     * 1 - WPA2 PSK
     * 2 - WPA PSK
     * 3 - WEP
     * 4 - NONE
     * @param capabilitie
     * @return
     */
    public static int getWifiEncryptType (String capabilitie) {
        if (TextUtils.isEmpty(capabilitie)){
            return -1;
        }

        int encryptType;

        if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
            encryptType = 0;
        } else if (capabilitie.contains("WPA2")) {
            encryptType = 1;
        } else if (capabilitie.contains("WPA")) {
            encryptType = 2;
        } else if (capabilitie.contains("WEP")) {
            encryptType = 3;
        } else {
            encryptType = 4;
        }

        return encryptType;
    }

    /**
     * @des 连接已经保存过配置的wifi
     * @param context
     * @param ssid
     */
    public static void connectWifi (Context context, String ssid) {
        if (!getWifiEnabled()) {
            return;
        }

        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration wc = new WifiConfiguration();
        wc.SSID = "\"" + ssid + "\"";
        WifiConfiguration configuration = getWifiConfig(context, ssid);
        if (configuration != null) {
            wm.disconnect();
            wm.enableNetwork(configuration.networkId, true);
        }

    }

    /**
     * @des 连接没有配置过的wifi
     * @param context
     * @param ssid
     * @param password
     * @param encryptType
     */
    public static void connectWifi (Context context, String ssid, String password, int encryptType) {

        if (!getWifiEnabled()){
            return;
        }

        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration wc = new WifiConfiguration();
        wc.allowedAuthAlgorithms.clear();
        wc.allowedGroupCiphers.clear();
        wc.allowedKeyManagement.clear();
        wc.allowedPairwiseCiphers.clear();
        wc.allowedProtocols.clear();
        wc.SSID = "\"" + ssid + "\"";

        WifiConfiguration configuration = getWifiConfig(context, ssid);
        if (configuration != null) {
            wm.removeNetwork(configuration.networkId);
        }
        switch (encryptType) {
            case 4:
                // 不加密
                wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                break;
            case 3:
                //wep 加密
                wc.hiddenSSID = true;
                wc.wepKeys[0] = "\"" + password +"\"";
                wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
                wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                break;
            case 0:
                // wpa/wap2加密
            case 1:
                // wpa2加密
            case 2:
                // wpa加密
                wc.preSharedKey = "\"" + password + "\"";
                wc.hiddenSSID = true;
                wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                wc.status = WifiConfiguration.Status.ENABLED;
                break;
            default:
                break;
        }

        int network = wm.addNetwork(wc);
        if (network == -1){
            connectWifi(context,ssid);
        }else {
            wm.disconnect();
            wm.enableNetwork(network, true);
        }
    }

    public static void disConnectWifi (Context context, int networkId) {
        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        wm.disableNetwork(networkId);
        wm.disconnect();
    }
}

相关文章

网友评论

      本文标题:Android Wifi相关操作

      本文链接:https://www.haomeiwen.com/subject/ubwvsktx.html