Android开发——自动连接指定SSID的wifi热点(不加密/加密)

2023-05-16

最近在做一个项目,其中涉及到一块“自动连接已存在的wifi热点”的功能,在网上查阅了大量资料,五花八门,但其中一些说的很简单,即不能实现傻瓜式的拿来就用,有些说的很详细,但其中不乏些许错误造成功能无法实现,经过浣熊多方努力,终于成功将功能实现,遂将一点点小成就拿出来与大家分享。


首先需要感谢这篇文章的作者:http://blog.chinaunix.net/uid-22342564-id-3228565.html

在这篇文章中,作者定义了一个wifi工具类,其中存在着操作wifi的各种方法,其中有一些错误我以改正,正确的代码如下(创建一个名为WifiAdmin.java的文件,以下代码中没有包声明和import,请自行添加):

public class WifiAdmin { 
    // 定义WifiManager对象  
    private WifiManager mWifiManager; 
    // 定义WifiInfo对象  
    private WifiInfo mWifiInfo; 
    // 扫描出的网络连接列表  
    private List<ScanResult> mWifiList; 
    // 网络连接列表  
    private List<WifiConfiguration> mWifiConfiguration; 
    // 定义一个WifiLock  
    WifiLock mWifiLock; 

 
    // 构造器  
    public WifiAdmin(Context context) { 
        // 取得WifiManager对象  
        mWifiManager = (WifiManager) context 
                .getSystemService(Context.WIFI_SERVICE); 
        // 取得WifiInfo对象  
        mWifiInfo = mWifiManager.getConnectionInfo(); 
    } 
 
    // 打开WIFI  
    public void openWifi() { 
        if (!mWifiManager.isWifiEnabled()) { 
            mWifiManager.setWifiEnabled(true); 
        } 
    } 
 
    // 关闭WIFI  
    public void closeWifi() { 
        if (mWifiManager.isWifiEnabled()) { 
            mWifiManager.setWifiEnabled(false); 
        } 
    } 
 
    // 检查当前WIFI状态  
    public int checkState() { 
        return mWifiManager.getWifiState(); 
    } 
 
    // 锁定WifiLock  
    public void acquireWifiLock() { 
        mWifiLock.acquire(); 
    } 
 
    // 解锁WifiLock  
    public void releaseWifiLock() { 
        // 判断时候锁定  
        if (mWifiLock.isHeld()) { 
            mWifiLock.acquire(); 
        } 
    } 
 
    // 创建一个WifiLock  
    public void creatWifiLock() { 
        mWifiLock = mWifiManager.createWifiLock("Test"); 
    } 
 
    // 得到配置好的网络  
    public List<WifiConfiguration> getConfiguration() { 
        return mWifiConfiguration; 
    } 
 
    // 指定配置好的网络进行连接  
    public void connectConfiguration(int index) { 
        // 索引大于配置好的网络索引返回  
        if (index > mWifiConfiguration.size()) { 
            return; 
        } 
        // 连接配置好的指定ID的网络  
        mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId, 
                true); 
    } 
 
    public void startScan() { 
        mWifiManager.startScan(); 
        // 得到扫描结果  
        mWifiList = mWifiManager.getScanResults(); 
        // 得到配置好的网络连接  
        mWifiConfiguration = mWifiManager.getConfiguredNetworks(); 
    } 
 
    // 得到网络列表  
    public List<ScanResult> getWifiList() { 
        return mWifiList; 
    } 
 
    // 查看扫描结果  
    public StringBuilder lookUpScan() { 
        StringBuilder stringBuilder = new StringBuilder(); 
        for (int i = 0; i < mWifiList.size(); i++) { 
            stringBuilder 
                    .append("Index_" + new Integer(i + 1).toString() + ":"); 
            // 将ScanResult信息转换成一个字符串包  
            // 其中把包括:BSSID、SSID、capabilities、frequency、level  
            stringBuilder.append((mWifiList.get(i)).toString()); 
            stringBuilder.append("/n"); 
        } 
        return stringBuilder; 
    }
 
    // 得到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(); 
    } 
 
    // 添加一个网络并连接  
    public void addNetwork(WifiConfiguration wcg) { 
	 int wcgID = mWifiManager.addNetwork(wcg); 
     boolean b =  mWifiManager.enableNetwork(wcgID, true); 
     System.out.println("a--" + wcgID);
     System.out.println("b--" + b);
    } 
 
    // 断开指定ID的网络  
    public void disconnectWifi(int netId) { 
        mWifiManager.disableNetwork(netId); 
        mWifiManager.disconnect(); 
    } 
 
//然后是一个实际应用方法,只验证过没有密码的情况:
 
    public WifiConfiguration CreateWifiInfo(String SSID, String Password, int Type) 
    { 
          WifiConfiguration config = new WifiConfiguration();   
           config.allowedAuthAlgorithms.clear(); 
           config.allowedGroupCiphers.clear(); 
           config.allowedKeyManagement.clear(); 
           config.allowedPairwiseCiphers.clear(); 
           config.allowedProtocols.clear(); 
          config.SSID = "\"" + SSID + "\"";   
          
          WifiConfiguration tempConfig = this.IsExsits(SSID);           
          if(tempConfig != null) {  
        	  mWifiManager.removeNetwork(tempConfig.networkId);  
          }
          
          if(Type == 1) //WIFICIPHER_NOPASS
          { 
               config.wepKeys[0] = ""; 
               config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 
               config.wepTxKeyIndex = 0; 
          } 
          if(Type == 2) //WIFICIPHER_WEP
          { 
              config.hiddenSSID = true;
              config.wepKeys[0]= "\""+Password+"\""; 
              config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); 
              config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); 
              config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); 
              config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 
              config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); 
              config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 
              config.wepTxKeyIndex = 0; 
          } 
          if(Type == 3) //WIFICIPHER_WPA
          { 
          config.preSharedKey = "\""+Password+"\""; 
          config.hiddenSSID = true;   
          config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);   
          config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);                         
          config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);                         
          config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);                    
          //config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);  
          config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
          config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
          config.status = WifiConfiguration.Status.ENABLED;   
          }
           return config; 
    } 
    
    private WifiConfiguration IsExsits(String SSID)  
    {  
        List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();  
           for (WifiConfiguration existingConfig : existingConfigs)   
           {  
             if (existingConfig.SSID.equals("\""+SSID+"\""))  
             {  
                 return existingConfig;  
             }  
           }  
        return null;   
    }
  
}
//分为三种情况:1没有密码2用wep加密3用wpa加密

改动主要集中在CreateWifiInfo这个方法中,并且添加了一个私有方法:

(1)将与方法的第三个参数有关的变量都改成int型,或者使用原作者的枚举型(存在bug需要改正),但枚举会在后续的开发中遇到些困难;

(2)在if(type == 3)中注释掉“config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);”,并添加“

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);“这两句,否则当wifi热点需要输入密码时,无法加入网络。

(3)在代码末尾添加了方法IsExsits,原因在于如果按照网上介绍的方法成功加入指定的wifi后,都会在终端的wifi列表中新添加一个以该指定ssid的网络,所以每运行一次程序,列表中就会多一个相同名字的ssid。而该方法就是检查wifi列表中是否有以输入参数为名的wifi热点,如果存在,则在CreateWifiInfo方法开始配置wifi网络之前将其移除,以避免ssid的重复:

WifiConfiguration tempConfig = this.IsExsits(SSID);           

          if(tempConfig != null) {  

          mWifiManager.removeNetwork(tempConfig.networkId);  

          }

以上便是wifi工具类的建立,之后就可以在其他部分实例化这个类,调用其中的方法完成加入指定ssid的wifi热点,还是先上代码吧,建立一个名为Test_wifiActivity.java的文件(同上,没有包含包声明和import语句):

public class Test_wifiActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        WifiAdmin wifiAdmin = new WifiAdmin(this);
        wifiAdmin.openWifi();
        wifiAdmin.addNetwork(wifiAdmin.CreateWifiInfo("XXX", "XXX", 3));
    }
}

很简单,如果是接入wifi,大体上只涉及到openWifi(打开wifi)、CreateWifiInfo(配置wifi网络信息)和addNetwork(添加配置好的网络并连接),对CreateWifiInfo进行简单的说明:第一参数是SSID的名称;第二个参数是指定SSID网络的密码,当不需要密码是置空(”“);第三个参数是热点类型:1-无密码 / 2-WEP密码验证(未测试)/ 3-WAP或WAP2 PSK密码验证。

最后就是在Manifest中添加相应的权限了:

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

如果按照上述的方法进行开发,就可以很傻瓜的通过改变Test_wifiActivity.java中的CreateWifiInfo方法的三个入口参数实现加入指定SSID的wifi热点了,无论该热点是否需要密码认证。

以上就是我对于自动连接指定SSID的wifi热点的学习心得,由于水平有限有些地方可能介绍错误,希望大家多多批评指正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android开发——自动连接指定SSID的wifi热点(不加密/加密) 的相关文章

  • VS2015编译过程中出现的MSB3705问题

    最近在研究teamtalk的源码 xff0c 使用vs2015进行编译 xff0c 因为电脑之前装过vs2015和vs2008 xff0c 之间有些冲突 xff0c 所以这次一次性卸载了vs2015和vs2008 xff0c vs2008是
  • tesseractOCR 识别数字问题

    拍下图片再进行识别 xff0c 所以如果图片的分辨率不高的话是无法准确识别的 xff0c 那么在拍出来进行截取时 xff0c 就需要保留原有的分辨率 xff0c 确保图片不会严重失真 xff08 归根结底保证图片不失真 xff09 处理图片
  • visual studio 2019 + WinDDK 7600.16385.0编写驱动

    驱动版本WinDDK 7600 16385 0 IDE xff1a visual studio 2019 新建空白项目 配置类型从exe改为生成文件 配置完后 xff0c 配置属性中就只剩基础配置了 xff0c 没有C C 43 43 链接
  • linux shell进度条

    1 最简单的一行进度条 bin bash num 61 0 str 61 39 39 max 61 100 postfix 61 39 39 39 39 39 39 39 39 while num le max do let index 6
  • 一篇深入解析BTF 实践指南

    BPF 是 Linux 内核中基于寄存器的虚拟机 xff0c 可安全 高效和事件驱动的方式执行加载至内核的字节码 与内核模块不同 xff0c BPF 程序经过验证以确保它们终止并且不包含任何可能锁定内核的循环 BPF 程序允许调用的内核函数
  • [c++]输入一组数据,逆序输出

    c 43 43 输入一组数据 xff0c 逆序输出 输入一组数据 xff0c 然后逆序输出 代码如下 xff1a include span class token operator lt span iostream span class t
  • Selenium WebDriver的工作原理

    先通过一个简单的类比说个好理解的 xff0c 这个比喻是我从美版知乎Quora上看到的 xff0c 觉得比较形象 好理解拿来用用 我们可以把WebDriver驱动浏览器类比成出租车司机开出租车 在开出租车时有三个角色 xff1a 乘客 xf
  • Python获取当前路径

    Refs https blog csdn net qq 15188017 article details 53991216 假设py文件路径为 F SEG myResearch myProject 2 test py Method 1 sy
  • vm虚拟机下载安装、iso镜像下载

    VMware官网下载 VMware Customer Connect The All In One VMware Product Support Portal iso镜像下载地址 1 centos xff08 推荐下载DVD IOS类型 x
  • Codeforces--501B--Misha and Changing Handles

    题目描述 xff1a Misha hacked the Codeforces site Then he decided to let all the users change their handles A user can now cha
  • Codeforces--1165A--Remainder

    题目描述 xff1a You are given a huge decimal number consisting of n digits It is guaranteed that this number has no leading z
  • Flutter web app三端跨平台双向桥接dart web开发

    Flutter web app三端跨平台双向桥接dart web开发 环境及项目运行步骤 xff1a 1 安装开发工具webstorm 2 官网下载flutter stable 1 5 4 xff0c 安装好并配置环境变量 3 执行cmd命
  • 正则表达式 linux shell

    正则表达式 热身 正则表达式 regular expression 描述了一种字符串匹配的模式 xff0c 可以用来检查一个串是否含有某种子串 将匹配的子串做替换或者从某个串中取出符合某个条件的子串等 例如 grep expr sed aw
  • 数据库中top的用法简述

    转自 xff1a 微点阅读 https www weidianyuedu com 数据库中top的用法的用法你知道吗 xff1f 下面小编就跟你们详细介绍下数据库中top的用法的用法 xff0c 希望对你们有用 数据库中top的用法的用法如
  • git第一次简单的使用与测试

    使用与测试git初次使用 xff1a 一 登陆自己的git xff0c 创建一个目录 最明显的标志 xff1a 创建说明 创建完成后 xff0c 需要复制创建的连接 xff1a 接下来要使用 二 创建完成后 xff0c 接下来就是 xff0
  • 【CCTC 2017】大数据在运营商、图计算、大规模机器学习以及云时代的运用与实践...

    CSDN现场报道 2017年5月18 19日 xff0c CSDN主办的中国云计算技术大会 xff08 CCTC xff09 在北京朝阳门悠唐皇冠假日酒店盛装启航 本次会议践行 云先行 xff0c 智未来 的主题 xff0c 在Keynot
  • 百度地图POI数据获取

    转载自 xff1a https blog csdn net baidu 26646129 article details 80464447 本文主要介绍百度地图POI数据获取 xff1a 从百度地图得到POI数据 xff0c 以json格式
  • ubuntu1804系统(xavier、NX)编译opencv报E:Unable to locate package libjasper-dev等最新解决方法

    opencv依赖包安装 sudo apt install libjasper1 libjasper dev 报错 xff1a 使用 Xavier NX安装opencv3 4 7 里说的解决方法 不行 xff1a 新的解决方法 xff1a 1
  • Spring Cloud微服务实战---1.2.采用HTTPS协议

    当前主流网站基本都开始支持HTTPS协议了 xff0c 对于电商网站来说 xff0c 由于对安全性的要求还是比较高的 xff0c 所以支持HTTPS协议是非常必要的 在本节中 xff0c 我们将把我们在上一节中开发的微服务 xff0c 启动
  • 如何运行GitHub上的代码

    如何从GitHub上下载自己需要的项目 xff1a 1 首先 xff0c 你要有一个自己的GitHub xff08 https github com xff09 的账号 关于如何注册GitHub的账号以及如何获取你的SSH密钥这个问题 xf

随机推荐