1. 程式人生 > >Android WIFI開發、掃描、連線和密碼驗證

Android WIFI開發、掃描、連線和密碼驗證

網上關於如何用程式碼設定wifi的文章一搜一大堆,我在此就不再添亂了,我就試著給大家談一談我遇到的問題吧。

首先,我在做有系統定製某App的wifi模組的專案需求時候,系統預設在出廠設定的時候wifi 是關閉的,當開啟連線wifi(獲取wifi資訊列表)的頁面的時候,我要初始化把wifi開啟,這個時候直接獲取wifi列表,卻遲遲沒有資料返回,後來我又監聽了

`WifiManager.SCAN_RESULTS_AVAILABLE_ACTION`,

這個廣播,收到廣播的時候再去獲取wifi資訊,果然,獲取到了,可是這時候有個問題,哎媽呀,當wifi開啟的時候,去呼叫這個

`mWifiManager.startScan();`

去掃描wifi ,等收到上面這個廣播之後再去獲取wifi,

mScanResults = mWifiManager.getScanResults();

但是這個期間卻要等待12左右才獲取到wifi的資料資訊,對於一個產品,使用者的體驗來說,肯定是不合理的,當時,我也找了好多資料,卻都沒怎麼說這方面的內容,苦了好久,也沒想明白,因為也不甜熟悉這一塊,後來就去Android 官網檢視Wifi相關的API ,收穫卻不小,但是這個Bug還是沒頭緒,於是就單獨寫了一個小Demo 來一步一步測試,貼程式碼,再詳細說明:

我們新增兩個按鈕,開啟Wifi,關閉wifi:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.xu.MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:layout_marginTop="111dp" android:text="跳轉" /> <Button android:id="@+id/open_wifi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/button1" android:layout_alignLeft="@+id/button1" android:layout_marginBottom="49dp" android:text="開啟WiFi" /> <Button android:id="@+id/close_wifi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:text="關閉wifi" /> </RelativeLayout>

MainActivity:

    /**
     * 開啟wifi功能
     * true:開啟成功;
     * false:開啟失敗
     */
    public boolean openWifi() {
        boolean bRet = true;
        if (!mWifiManager.isWifiEnabled()) {
            bRet = mWifiManager.setWifiEnabled(true);
        }
        return bRet;
    }

    /**
     * Function:關閉wifi
     * @return<br>
     */
    public boolean closeWifi() {
        if (mWifiManager.isWifiEnabled()) {
            return mWifiManager.setWifiEnabled(false);
        }
        return false;
    }

當進入這個頁面的時候就去註冊廣播,然後先去手動開啟wifi,呼叫openWifi()方法,

    /**
     * 註冊廣播
     */
    private void registerBroadcast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        registerReceiver(mReceiver, filter);
    }

打印出相應的Log時間差資訊:

        /**
         * 開啟wifi 
         */
        openWifi.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                openWifi();
                Log.d(TAG, "開啟" + DateUtils.getCurrentDateString());
                mWifiManager.startScan();
            }
        });

        /**
         * 關閉wifi
         */
        closeWifi.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                closeWifi();
                Log.d(TAG, "關閉" + DateUtils.getCurrentDateString());
            }
        });

接收廣播的時候也輸出相應的日誌資訊,如果在接收到

WifiManager.SCAN_RESULTS_AVAILABLE_ACTION

這個廣播的時候再去掃描wifi資訊;

mWifiManager.startScan();
mScanResults = mWifiManager.getScanResults();

這個時候去看log輸出的接收到這個廣播的時間,程式碼如下:

    /**
     * 廣播接收,監聽網路
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            // wifi已成功掃描到可用wifi。
            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                Log.d(TAG, "接收到" +DateUtils.getCurrentDateString());
                mWifiManager.startScan();
                mScanResults = mWifiManager.getScanResults();
                Log.d(TAG, "mScanResults.size()===" + mScanResults.size());
            } 
        }
    };

這個時候我就監聽了這一個廣播,log日誌看圖:

這裡寫圖片描述

看上面的時間差就等候了近13秒左右才出來結果,就是為了解決這個問題,又去看有關的資料和API,後來有新增一個廣播。

filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

更改後,在監聽這個系統wifi開啟時候,就去掃描wifi,

    /**
     * 廣播接收,監聽網路
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            // wifi已成功掃描到可用wifi。
            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                Log.d(TAG, "接收到" +DateUtils.getCurrentDateString());
                mScanResults = mWifiManager.getScanResults();
                Log.d(TAG, "mScanResults.size()===" + mScanResults.size());

            } 
            //系統wifi的狀態
            else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                int wifiState = intent.getIntExtra(
                        WifiManager.EXTRA_WIFI_STATE, 0);
                switch (wifiState) {
                case WifiManager.WIFI_STATE_ENABLED:
                    Log.d(TAG, "WiFi已啟用" + DateUtils.getCurrentTime());
                    mWifiManager.startScan(); <<<這裡
                    break;
                case WifiManager.WIFI_STATE_DISABLED:
                    Log.d(TAG, "Wifi已關閉" + DateUtils.getCurrentTime());
                    break;
                }
            }
        }
    };

執行後看下log日誌:

這裡寫圖片描述

demo會放在後面附件裡

驚奇的發現,哇哦!這個速度到wifi資料顯示的時間差就在2秒左右哦,非常棒!這個就是我們想要的效果~,當然了,其實還要更多的方法同樣能實現這樣的效果,本人能力有限,還是自己不夠用心,基礎不紮實,不夠努力,導致了這樣,那樣的問題。在別人眼裡,雖然沒什麼難度,但是終究自己弄了個小demo 測試了出來,就把遇到問題就分享給了大家,以後慢慢學會寫部落格~

等這段時間忙完了,我正整理一下連線wifi的相關操作的完整demo,到時候再更新部落格~