在上一篇文章《Android開發(fā)實踐:WIFI掃描功能的封裝》介紹了如何利用Andriod的API實現(xiàn)WIFI的掃描,本文則重點講述一下如何連接WIFI吧,在此,也給出一個封裝WIFI連接過程的類,提供簡單的接口以供在各個代碼工程中復(fù)用。
站在用戶的角度思考問題,與客戶深入溝通,找到富縣網(wǎng)站設(shè)計與富縣網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:做網(wǎng)站、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名注冊、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋富縣地區(qū)。與WIFI掃描類似,WIFI的連接同樣是一個耗時的過程,所以需要放到線程中執(zhí)行,通過回調(diào)來通知調(diào)用者連接結(jié)果。該回調(diào)接口的定義如下:
public interface WifiConnectListener { public void OnWifiConnectCompleted( boolean isConnected ); }
從Android的WIFI Setting可以看出,一般添加一個新的WIFI連接,需要給出三個信息,一個是WIFI的SSID,一個是WIFI的密碼,另一個是WIFI的加密類型,不同的加密方式,連接時程序中的配置是不同的,這里定義一個枚舉,給出四種常見的加密類型:
public enum SecurityMode { OPEN, WEP, WPA, WPA2 }
Android的WIFI連接過程,總體上分為三步,第一步,添加網(wǎng)絡(luò)配置,第二步,根據(jù)網(wǎng)絡(luò)配置連接WIFI,第三步,監(jiān)聽系統(tǒng)的WIFI連接狀態(tài)消息。下面就直接給出示例代碼,關(guān)鍵的地方都在代碼中注釋了。
package com.example.testwifi; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; public class WifiConnector { private static final int WIFI_CONNECT_TIMEOUT = 20; //連接WIFI的超時時間 private Context mContext; private WifiManager mWifiManager; private Lock mLock; private Condition mCondition; private WiFiConncetReceiver mWifiConnectReceiver; private WifiConnectListener mWifiConnectListener; private boolean mIsConnnected = false; private int mNetworkID = -1; //網(wǎng)絡(luò)加密模式 public enum SecurityMode { OPEN, WEP, WPA, WPA2 } //通知連接結(jié)果的監(jiān)聽接口 public interface WifiConnectListener { public void OnWifiConnectCompleted( boolean isConnected ); } public WifiConnector( Context context , WifiConnectListener listener ) { mContext = context; mLock = new ReentrantLock(); mCondition = mLock.newCondition(); mWifiManager=(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); mWifiConnectReceiver = new WiFiConncetReceiver(); mWifiConnectListener = listener; } public void connect( final String ssid, final String password, final SecurityMode mode ) { new Thread(new Runnable() { @Override public void run() { //如果WIFI沒有打開,則打開WIFI if( !mWifiManager.isWifiEnabled() ) { mWifiManager.setWifiEnabled(true); } //注冊連接結(jié)果監(jiān)聽對象 mContext.registerReceiver(mWifiConnectReceiver, new IntentFilter(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)); //連接指定SSID if( !onConnect(ssid,password,mode) ) { mWifiConnectListener.OnWifiConnectCompleted(false); } else { mWifiConnectListener.OnWifiConnectCompleted(true); } //刪除注冊的監(jiān)聽類對象 mContext.unregisterReceiver(mWifiConnectReceiver); } }).start(); } protected boolean onConnect( String ssid, String password, SecurityMode mode ) { //添加新的網(wǎng)絡(luò)配置 WifiConfiguration cfg = new WifiConfiguration(); cfg.SSID = "\"" + ssid + "\""; if( password !=null && !"".equals(password) ) { //這里比較關(guān)鍵,如果是WEP加密方式的網(wǎng)絡(luò),密碼需要放到cfg.wepKeys[0]里面 if( mode == SecurityMode.WEP ) { cfg.wepKeys[0] = "\"" + password + "\""; cfg.wepTxKeyIndex = 0; } else { cfg.preSharedKey = "\"" + password + "\""; } } cfg.status = WifiConfiguration.Status.ENABLED; //添加網(wǎng)絡(luò)配置 mNetworkID = mWifiManager.addNetwork(cfg); mLock.lock(); mIsConnnected = false; //連接該網(wǎng)絡(luò) if( !mWifiManager.enableNetwork(mNetworkID , true) ) { mLock.unlock(); return false; } try { //等待連接結(jié)果 mCondition.await(WIFI_CONNECT_TIMEOUT, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } mLock.unlock(); return mIsConnnected; } //監(jiān)聽系統(tǒng)的WIFI連接消息 protected class WiFiConncetReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(intent.getAction())) { return; } mLock.lock(); WifiInfo info = mWifiManager.getConnectionInfo(); if ( info.getNetworkId()==mNetworkID && info.getSupplicantState() == SupplicantState.COMPLETED ) { mIsConnnected = true; mCondition.signalAll(); } mLock.unlock(); } } }
與WIFI掃描的封裝代碼類似,這里也用到了Lock和Condition,就是為了阻塞地等待WIFI連接的結(jié)果,保證正確的registerReceiver和unregisterReceiver網(wǎng)絡(luò)連接狀態(tài)監(jiān)聽對象,同時,設(shè)置了WIFI連接超時,防止由于WIFI模塊的問題導(dǎo)致界面收不到回調(diào)而長時間“卡死”。
另外,AndroidManifest.xml文件中記得添加權(quán)限支持哦:
這個WIFI連接類的封裝就分享到這里啦,希望對初學(xué)者有幫助,java文件見博文后面的附件,有任何疑問歡迎留言或者來信lujun.hust@gmail.com交流,或者關(guān)注我的新浪微博 @盧_俊 獲取最新的文章和資訊。
附件:http://down.51cto.com/data/2364418另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。