最近在做一个项目,其中涉及到一块“自动连接已存在的wifi热点”的功能,在网上查阅了大量资料,五花八门,但其中一些说的很简单,即不能实现傻瓜式的拿来就用,有些说的很详细,但其中不乏些许错误造成功能无法实现,经过浣熊多方努力,终于成功将功能实现,遂将一点点小成就拿出来与大家分享。
在这篇文章中,作者定义了一个wifi工具类,其中存在着操作wifi的各种方法,其中有一些错误我以改正,正确的代码如下(创建一个名为WifiAdmin.java的文件,以下代码中没有包声明和import,请自行添加):
1. public class WifiAdmin {
2. // 定义WifiManager对象
3. private WifiManager mWifiManager;
4. // 定义WifiInfo对象
5. private WifiInfo mWifiInfo;
6. // 扫描出的网络连接列表
7. private List<ScanResult> mWifiList;
8. // 网络连接列表
9. private List<WifiConfiguration> mWifiConfiguration;
10. // 定义一个WifiLock
11. WifiLock mWifiLock;
12.
13.
14. // 构造器
15. public WifiAdmin(Context context) {
16. // 取得WifiManager对象
17. mWifiManager = (WifiManager) context
18. .getSystemService(Context.WIFI_SERVICE);
19. // 取得WifiInfo对象
20. mWifiInfo = mWifiManager.getConnectionInfo();
21. }
22.
23. // 打开WIFI
24. public void openWifi() {
25. if (!mWifiManager.isWifiEnabled()) {
26. true);
27. }
28. }
29.
30. // 关闭WIFI
31. public void closeWifi() {
32. if (mWifiManager.isWifiEnabled()) {
33. false);
34. }
35. }
36.
37. // 检查当前WIFI状态
38. public int checkState() {
39. return mWifiManager.getWifiState();
40. }
41.
42. // 锁定WifiLock
43. public void acquireWifiLock() {
44. mWifiLock.acquire();
45. }
46.
47. // 解锁WifiLock
48. public void releaseWifiLock() {
49. // 判断时候锁定
50. if (mWifiLock.isHeld()) {
51. mWifiLock.acquire();
52. }
53. }
54.
55. // 创建一个WifiLock
56. public void creatWifiLock() {
57. "Test");
58. }
59.
60. // 得到配置好的网络
61. public List<WifiConfiguration> getConfiguration() {
62. return mWifiConfiguration;
63. }
64.
65. // 指定配置好的网络进行连接
66. public void connectConfiguration(int index) {
67. // 索引大于配置好的网络索引返回
68. if (index > mWifiConfiguration.size()) {
69. return;
70. }
71. // 连接配置好的指定ID的网络
72. mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
73. true);
74. }
75.
76. public void startScan() {
77. mWifiManager.startScan();
78. // 得到扫描结果
79. mWifiList = mWifiManager.getScanResults();
80. // 得到配置好的网络连接
81. mWifiConfiguration = mWifiManager.getConfiguredNetworks();
82. }
83.
84. // 得到网络列表
85. public List<ScanResult> getWifiList() {
86. return mWifiList;
87. }
88.
89. // 查看扫描结果
90. public StringBuilder lookUpScan() {
91. new StringBuilder();
92. for (int i = 0; i < mWifiList.size(); i++) {
93. stringBuilder
94. "Index_" + new Integer(i + 1).toString() + ":");
95. // 将ScanResult信息转换成一个字符串包
96. // 其中把包括:BSSID、SSID、capabilities、frequency、level
97. stringBuilder.append((mWifiList.get(i)).toString());
98. "/n");
99. }
100. return stringBuilder;
101. }
102.
103. // 得到MAC地址
104. public String getMacAddress() {
105. return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
106. }
107.
108. // 得到接入点的BSSID
109. public String getBSSID() {
110. return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();
111. }
112.
113. // 得到IP地址
114. public int getIPAddress() {
115. return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
116. }
117.
118. // 得到连接的ID
119. public int getNetworkId() {
120. return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
121. }
122.
123. // 得到WifiInfo的所有信息包
124. public String getWifiInfo() {
125. return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();
126. }
127.
128. // 添加一个网络并连接
129. public void addNetwork(WifiConfiguration wcg) {
130. int wcgID = mWifiManager.addNetwork(wcg);
131. boolean b = mWifiManager.enableNetwork(wcgID, true);
132. "a--" + wcgID);
133. "b--" + b);
134. }
135.
136. // 断开指定ID的网络
137. public void disconnectWifi(int netId) {
138. mWifiManager.disableNetwork(netId);
139. mWifiManager.disconnect();
140. }
141.
142. //然后是一个实际应用方法,只验证过没有密码的情况:
143.
144. public WifiConfiguration CreateWifiInfo(String SSID, String Password, int Type)
145. {
146. new WifiConfiguration();
147. config.allowedAuthAlgorithms.clear();
148. config.allowedGroupCiphers.clear();
149. config.allowedKeyManagement.clear();
150. config.allowedPairwiseCiphers.clear();
151. config.allowedProtocols.clear();
152. "\"" + SSID + "\"";
153.
154. this.IsExsits(SSID);
155. if(tempConfig != null) {
156. mWifiManager.removeNetwork(tempConfig.networkId);
157. }
158.
159. if(Type == 1) //WIFICIPHER_NOPASS
160. {
161. 0] = "";
162. config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
163. 0;
164. }
165. if(Type == 2) //WIFICIPHER_WEP
166. {
167. true;
168. 0]= "\""+Password+"\"";
169. config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
170. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
171. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
172. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
173. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
174. config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
175. 0;
176. }
177. if(Type == 3) //WIFICIPHER_WPA
178. {
179. "\""+Password+"\"";
180. true;
181. config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
182. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
183. config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
184. config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
185. //config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
186. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
187. config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
188. config.status = WifiConfiguration.Status.ENABLED;
189. }
190. return config;
191. }
192.
193. private WifiConfiguration IsExsits(String SSID)
194. {
195. List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
196. for (WifiConfiguration existingConfig : existingConfigs)
197. {
198. if (existingConfig.SSID.equals("\""+SSID+"\""))
199. {
200. return existingConfig;
201. }
202. }
203. return null;
204. }
205.
206. }
207. //分为三种情况:1没有密码2用wep加密3用wpa加密
改动主要集中在CreateWifiInfo这个方法中,并且添加了一个私有方法:
(1)将与方法的第三个参数有关的变量都改成int型,或者使用原作者的枚举型(存在bug需要改正),但枚举会在后续的开发中遇到些困难;
(2)在if(type == 3)中注释掉“config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);”,并添加“
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);“这两句,否则当wifi热点需要输入密码时,无法加入网络。
(3)在代码末尾添加了方法IsExsits,原因在于如果按照网上介绍的方法成功加入指定的wifi后,都会在终端的wifi列表中新添加一个以该指定ssid的网络,所以每运行一次程序,列表中就会多一个相同名字的ssid。而该方法就是检查wifi列表中是否有以输入参数为名的wifi热点,如果存在,则在CreateWifiInfo方法开始配置wifi网络之前将其移除,以避免ssid的重复:
this.IsExsits(SSID);
if(tempConfig != null) {
mWifiManager.removeNetwork(tempConfig.networkId);
}
以上便是wifi工具类的建立,之后就可以在其他部分实例化这个类,调用其中的方法完成加入指定ssid的wifi热点,还是先上代码吧,建立一个名为Test_wifiActivity.java的文件(同上,没有包含包声明和import语句):
1. public class Test_wifiActivity extends Activity {
2. /** Called when the activity is first created. */
3. @Override
4. public void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.main);
7.
8. new WifiAdmin(this);
9. wifiAdmin.openWifi();
10. "XXX", "XXX", 3));
11. }
12. }
很简单,如果是接入wifi,大体上只涉及到openWifi(打开wifi)、CreateWifiInfo(配置wifi网络信息)和addNetwork(添加配置好的网络并连接),对CreateWifiInfo进行简单的说明:第一参数是SSID的名称;第二个参数是指定SSID网络的密码,当不需要密码是置空(”“);第三个参数是热点类型:1-无密码 / 2-WEP密码验证(未测试)/ 3-WAP或WAP2 PSK密码验证。
最后就是在Manifest中添加相应的权限了:
1. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" ></uses-permission>
2. "android.permission.CHANGE_WIFI_STATE" ></uses-permission>
3. "android.permission.ACCESS_NETWORK_STATE" ></uses-permission>
4. "android.permission.ACCESS_WIFI_STATE" ></uses-permission>
如果按照上述的方法进行开发,就可以很傻瓜的通过改变Test_wifiActivity.java中的CreateWifiInfo方法的三个入口参数实现加入指定SSID的wifi热点了,无论该热点是否需要密码认证。
以上就是我对于自动连接指定SSID的wifi热点的学习心得,由于水平有限有些地方可能介绍错误,希望大家多多批评指正!