WiFi和热点开发

本文介绍了Android系统中关于WiFi的API使用,如开启/关闭WiFi、获取网络状态及配置信息。强调了搜索网络的异步性质,以及在断开和连接网络时应注意的细节。在Android 6.0及以上版本,app只能修改自己创建的WiFi配置,文中给出了适应此变化的正确连接方式。至于热点功能,由于系统限制,大部分操作需通过反射实现,且通常需要系统签名权限。
摘要由CSDN通过智能技术生成

WIFI的有关操作,系统提供了完备的API,供第三方app调用;
比如,开启和关闭wifi,获取wifi的状态,获取已保存的配置信息:getConfiguredNetworks(),获取当前连接的网络信息:getConnectionInfo() 等。需要注意的是搜索网络(startScan())并不是同步调用,搜索网络的方法本身不会返回结果,而是搜索完成后,会收到WifiManager.SCAN_RESULTS_AVAILABLE_ACTION类型的广播,在收到该广播后调用getScanResults() 才可获取到覆盖的网络信息,包括SSID、信号强度、加密类型等;此外,需注意断开某个网络,调用disableNetwork(netId) 方法后,对应的网络会进入已停用的状态,除非再次主动调用enableNetwork 方法激活该网络,否则系统都不会再自动连接到该网络。enableNetwork 可以传两个参数,其中第一个是网络id,第二个代表是否同时断开其他的网络,如果传递false就是代表仅做激活不一定连接(如果当前已经有连接就不会重新连接),如果传递true就是代表不仅做激活而且确保连接到当前传递的网络(如果当前已经有其他连接就会断开并重新连接)。
连接到某个网络enableNetwork(tempConfig.networkId, true) 时,也许有的小伙伴们会这么编码:

WifiConfiguration wifiConfig = CreateWifiInfo(SSID, Password);
if (wifiConfig == null) {
    return false;
}
WifiConfiguration tempConfig = IsExsits(context, SSID);//判断是否已在配置网络集
if (tempConfig != null) {
    wifiManager.removeNetwork(tempConfig.networkId);
}
int netID = wifiManager.addNetwork(wifiConfig);
boolean bRet = wifiManager.enableNetwork(netID, true);

但是在android 6.0及以上版本以上代码有问题。
android 6.0开始app只能修改自己创建的WifiConfiguration对象的状态,而不再允许修改或删除由用户或其它app创建的WifiConfiguration对象,因此addNetwork() 可能返回“-1”,从而导致执行enableNetwork 方法出错,因此最合适的做法参考如下:

WifiConfiguration tempConfig = IsExsits(SSID);
if (tempConfig != null) {
    bRet = wifiManager.enableNetwork(tempConfig.networkId, true);
}else{
    WifiConfiguration wifiConfig = CreateWifiInfo(SSID, Password);
    if (wifiConfig == null) {
        logd("wifiConfig create failed.");
        return false;
    }
    int netID = wifiManager.addNetwork(wifiConfig);
    bRet = wifiManager.enableNetwork(netID, true);
}

先判断要连接的网络信息是否已经在已配置列表中,如果在就直接调用enableNetwork方法,否则就先创建再调用enableNetwork方法,创建的方法参考如下:

private WifiConfiguration CreateWifiInfo(String SSID, String Password) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";

        config.preSharedKey = "\"" + Password + "\"";
        config.hiddenSSID = true;

        // [WPA2-PSK-TKIP]
        config.preSharedKey = "\"" + Password + "\"";
        // config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        config.status = WifiConfiguration.Status.ENABLED;

        WifiConfiguration tempConfig = config;
        if (tempConfig != null) {
        }
        return config;
    }

热点的有关操作,系统就没有完全开放,除非你是具有系统签名的app。
比如,关闭、打开热点(设置SSID和密码,设置最大连接数,设置信道),获取热点状态,获取热点配置信息,判断热点是否开启等,基本都采用了反射,而且打开热点必须是系统签名的app才能正确执行。

private static boolean isWifiApEnabled(WifiManager wifiManager) {
        try {
            Method method = wifiManager.getClass().getMethod("isWifiApEnabled");
            method.setAccessible(true);
            return (Boolean) method.invoke(wifiManager);

        } catch (NoSuchMethodException e) {
            logd(e);
        } catch (Exception e) {
            logd(e);
        }

        return false;
    }
public WifiConfiguration getApConfig() {
        if (isWifiApEnabled(mWifiManager)) {
            try {
                Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
                method.setAccessible(true);
                WifiConfiguration config = (WifiConfiguration) method.invoke(mWifiManager);
                return config;
            } catch (Exception e) {
                logd(e);
            }
        }
        return null;
    }
public static boolean setWifiApEnabled(Context context, String ssid,
            String key, Boolean enabled) {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (enabled) { // disable WiFi in any case
            // wifi和热点不能同时打,所以打热点的时候需要关闭wifi
            setWifiEnable(context, false);
        }
        try {
            // 热点的配置类
            WifiConfiguration apConfig = new WifiConfiguration();
            apConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            apConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            apConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            // 配置热点的名称(可以在名字后面加点随机数)
            apConfig.SSID = ssid;
            //设置信道 111 之间的随机整数
            apConfig.apChannel=new Random().nextInt(11)+1;
            apConfig.softApMaxNumSta= AppConfig.numClients;
            // 配置热点的密码
            apConfig.preSharedKey = key;
            // 配置加密方式
            //apConfig.allowedKeyManagement.set(WPA2_PSK);
            apConfig.allowedKeyManagement.set(1);
            // 通过反射调用设置热点
            Method method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
            // 返回热点打开状
            return (Boolean) method.invoke(wifiManager, apConfig, enabled);
        } catch (Exception e) {
            logd("setWifiApEnabled:" + e.getMessage());
            return false;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值