美文网首页
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