1. 程式人生 > >Android WIFI功能——WifiManager

Android WIFI功能——WifiManager

個人部落格:haichenyi.com。感謝關注

  之前做了關於Android wifi的相關功能,這裡做一個記錄

第一步:獲取WifiManager

WifiManager wifiMgr = (WifiManager)Context.getSystemService(Context.WIFI_SERVICE);

第二步:獲取周圍熱點資訊和已連線wifi資訊

List<ScanResult> scanResults = wifiMgr.getScanResults();//掃描到的周圍熱點資訊
WifiInfo info = wifiMgr.getConnectionInfo();//已連線wifi資訊

這裡我說一下幾個欄位的意思:

  public String name;//ssid對應的wifi名字
  public String capabilities;//用來判斷是否有密碼
  public int level;//訊號等級,這裡是負數
  public String BSSID;//macid

這裡我需要強調的就是level,是負數,負數越大,訊號越好

第三步:檢測wifi資訊,這裡我給出幾個工具類

/**
   * 連線有密碼的wifi.
   *
   * @param SSID     ssid
   * @param Password Password
   * @return
apConfig */
private WifiConfiguration setWifiParamsPassword(String SSID, String Password) { WifiConfiguration apConfig = new WifiConfiguration(); apConfig.SSID = "\"" + SSID + "\""; apConfig.preSharedKey = "\"" + Password + "\""; //不廣播其SSID的網路 apConfig.hiddenSSID = true; apConfig.status = WifiConfiguration.Status.ENABLED; //公認的IEEE 802.11驗證演算法。
apConfig.allowedAuthAlgorithms.clear(); apConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); //公認的的公共組密碼 apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); //公認的金鑰管理方案 apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); //密碼為WPA。 apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); //公認的安全協議。 apConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN); return apConfig; } /** * 連線沒有密碼wifi. * * @param ssid ssid * @return configuration */ private WifiConfiguration setWifiParamsNoPassword(String ssid) { WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = "\"" + ssid + "\""; configuration.status = WifiConfiguration.Status.ENABLED; configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); configuration.allowedPairwiseCiphers .set(WifiConfiguration.PairwiseCipher.TKIP); configuration.allowedPairwiseCiphers .set(WifiConfiguration.PairwiseCipher.CCMP); configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); return configuration; } public static final int WIFI_NO_PASS = 0; private static final int WIFI_WEP = 1; private static final int WIFI_PSK = 2; private static final int WIFI_EAP = 3; /** * 判斷是否有密碼. * * @param result ScanResult * @return 0 */ public static int getSecurity(MyScanResult result) { if (null != result && null != result.capabilities) { if (result.capabilities.contains("WEP")) { return WIFI_WEP; } else if (result.capabilities.contains("PSK")) { return WIFI_PSK; } else if (result.capabilities.contains("EAP")) { return WIFI_EAP; } } return WIFI_NO_PASS; }

上面三個工具類,一個用來判斷是否需要密碼,另外兩個用來連線wifi

連線wifi

//需要密碼
wifiMgr.enableNetwork(wifiMgr.addNetwork(
                    setWifiParamsPassword(mClickResult.name, password)), true);
//不需要密碼
wifiMgr.enableNetwork(wifiMgr.addNetwork(setWifiParamsNoPassword(mClickResult.name)),
              true);

wifi監聽

PS:關於wifi狀態的監聽,就是監聽你當前的網路狀態即可。

<receiver android:name=".receiver.NetworkReceiver">
            <intent-filter>
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
                <action android:name="android.net.wifi.STATE_CHANGE"/>
                <action android:name="android.net.wifi.supplicant.STATE_CHANGE"/>
                <action android:name="android.net.wifi.NETWORK_IDS_CHANGED"/>
            </intent-filter>
        </receiver>

首先在你的清單檔案註冊這四種action的廣播,這裡給出我的網路監聽廣播

/**
 * Author: 海晨憶.
 * Date: 2018/1/10
 * Desc: 網路廣播監聽
 */
public class NetworkReceiver extends BroadcastReceiver {
  public static final int STATE1 = 1;//密碼錯誤
  public static final int STATE2 = 2;//連線成功
  public static final int STATE3 = 3;//連線失敗
  public static final int STATE4 = 4;//正在獲取ip地址
  public static final int STATE5 = 5;//正在連線

  @Override
  public void onReceive(Context context, Intent intent) {
    if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(intent.getAction())) {
      //密碼錯誤廣播,是不是正在獲得IP地址
      int linkWifiResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
      if (linkWifiResult == WifiManager.ERROR_AUTHENTICATING) {
        //密碼錯誤
        ToastUtils.showTipMsg(R.string.password_wrong);
        sendNetworkStateChange(new NetWorkInfo().setState(STATE1));
      }
      SupplicantState supplicantState = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
      NetworkInfo.DetailedState state = WifiInfo.getDetailedStateOf(supplicantState);
      Log.v(Constants.HTTP_WZ, state.name());
      if (state == NetworkInfo.DetailedState.CONNECTING) {
        //正在連線
        ToastUtils.showTipMsg(R.string.linking);
        sendNetworkStateChange(new NetWorkInfo().setState(STATE5));
      } else if (state == NetworkInfo.DetailedState.FAILED
          || state == NetworkInfo.DetailedState.DISCONNECTING) {
        //連線失敗
        sendNetworkStateChange(new NetWorkInfo().setState(STATE3));
        ToastUtils.showTipMsg(R.string.linked_failed);
      } else if (state == NetworkInfo.DetailedState.CONNECTED) {
        //連線成功
        ToastUtils.showTipMsg(R.string.linked_success);
      } else if (state == NetworkInfo.DetailedState.OBTAINING_IPADDR) {
        //正在獲取ip地址
        sendNetworkStateChange(new NetWorkInfo().setState(STATE4));
      } else if (state == NetworkInfo.DetailedState.IDLE) {
        //閒置的
        ConnectivityManager connectManager = (ConnectivityManager) BaseApplication.getInstance()
            .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = null;
        if (connectManager != null) {
          activeNetworkInfo = connectManager.getActiveNetworkInfo();
        }
        if (activeNetworkInfo == null) {
          sendNetworkStateChange(new NetWorkInfo().setState(STATE3));
          ToastUtils.showTipMsg(R.string.linked_failed);
        }
      }
    } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
      // 監聽wifi的開啟與關閉,與wifi的連線無關
      int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
      Log.v(Constants.HTTP_WZ, "wifiState:" + wifiState);
      switch (wifiState) {
        case WifiManager.WIFI_STATE_DISABLING://正在停止0
          ToastUtils.showTipMsg(R.string.close_wifi);
          break;
        case WifiManager.WIFI_STATE_DISABLED://已停止1
          break;
        case WifiManager.WIFI_STATE_UNKNOWN://未知4
          break;
        case WifiManager.WIFI_STATE_ENABLING://正在開啟2
          ToastUtils.showTipMsg(R.string.opening_wifi);
          break;
        case WifiManager.WIFI_STATE_ENABLED://已開啟3
          break;
        default:
          break;
      }
    } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
      // 監聽wifi的連線狀態即是否連上了一個有效無線路由
      Parcelable parcelableExtra = intent
          .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
      if (null != parcelableExtra) {
        // 獲取聯網狀態的NetWorkInfo物件
        NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
        //獲取的State物件則代表著連線成功與否等狀態
        NetworkInfo.State state = networkInfo.getState();
        //判斷網路是否已經連線
        boolean isConnected = state == NetworkInfo.State.CONNECTED;
        Log.v(Constants.HTTP_WZ, "isConnected:" + isConnected);
        if (isConnected) {
          ToastUtils.showTipMsg(R.string.linked_success);
          sendNetworkStateChange(new NetWorkInfo().setState(STATE2));
        }
      }
    }
  }

  /**
   * 傳送網路狀態eventBus.
   *
   * @param info info
   */
  private void sendNetworkStateChange(NetWorkInfo info) {
    EventBus.getDefault().post(info);
  }

  @SuppressWarnings("unused")
  private String getConnectionType(int type) {
    String connType = "";
    if (type == ConnectivityManager.TYPE_MOBILE) {
      connType = "行動網路";
    } else if (type == ConnectivityManager.TYPE_WIFI) {
      connType = "WIFI網路";
    }
    return connType;
  }

  public static class NetWorkInfo {
    public int state;//1密碼錯誤,2:連線成功,3:連線失敗

    private NetWorkInfo setState(int state) {
      this.state = state;
      return this;
    }
  }
}

註釋應該寫的很清楚,我就不做過多的解釋了。