android开发步步为营之48:通过WifiManager自动连上某个wifi热点

        最近参加了个某个创业公司的面试,他们做了个应用,就是用户打开他们的应用就可以提供免费上网的功能,然后面试的过程中,那哥们说,你对wifi这些协议你懂吗?需要用到比较底层的东西哦,我勒个去,就这么一个上网功能就需要很底层吗?搞得很高深的样子,真是底层是涉及到修改android的框架了,修改手机ROM了,你们做到这一步了吗?没有吧,只是在android框架提供api基础上实现的,为此,我今天特意实验了一把。也就10几分钟就搞定的事情,我被你们懵到了,额。。。

       开发过程中主要用到WifiManager这个系统自带的服务,它有如下几个状态

     WifiManager.WIFI_STATE_DISABLED: //wifi不可用

     WifiManager.WIFI_STATE_DISABLING://wifi 正在关闭或者断开

     WifiManager.WIFI_STATE_ENABLED://wifi已经打开可用

     WifiManager.WIFI_STATE_ENABLING://wifi正在打开或者连接

     WifiManager.WIFI_STATE_UNKNOWN://未知消息

     好,开始我们的实验:

     第一步:AndroidManifest.xml添加相关权限

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

 

     第二步:新建测试页面/study/res/layout/activity_wifi.xml

  

<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=".MainActivity" >

    <Button
        android:id="@+id/btnWifi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="47dp"
        android:text="自动连上wifi" />

</RelativeLayout>

 

       第三步:实现Activity,WifiManagerTestActivity.java

/**
 * 自动选择连上某个wifi信号
 */
package com.figo.study;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
 * @author zhuzhifei 
 */
public class WifiManagerTestActivity extends Activity {
 private Button btnWifi;
 WifiManager wifiManager;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_wifi);
  //获取wifi管理服务
  wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

  btnWifi = (Button) findViewById(R.id.btnWifi);
  btnWifi.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {
    // TODO Auto-generated method stub
//    connect("newhome","newhome123",WifiCipherType.WIFICIPHER_WEP);
    //启动wifi
    connect("newhome","newhome123",WifiCipherType.WIFICIPHER_WPA);
   }
  });

 }

 private static final String TAG = WifiManagerTestActivity.class
   .getSimpleName();

 

 // 定义几种加密方式,一种是WEP,一种是WPA,还有没有密码的情况
 public enum WifiCipherType {
  WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
 }


 // 提供一个外部接口,传入要连接的无线网ssid,password,
 public void connect(String ssid, String password, WifiCipherType type) {
  Thread thread = new Thread(new ConnectRunnable(ssid, password, type));
  thread.start();
 }

 // 查看以前是否也配置过这个网络
 private WifiConfiguration isExsits(String SSID) {
  List<WifiConfiguration> existingConfigs = wifiManager
    .getConfiguredNetworks();
  for (WifiConfiguration existingConfig : existingConfigs) {
   if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
    return existingConfig;
   }
  }
  return null;
 }

 private WifiConfiguration createWifiInfo(String SSID, String Password,
   WifiCipherType Type) {
  WifiConfiguration config = new WifiConfiguration();
  config.allowedAuthAlgorithms.clear();
  config.allowedGroupCiphers.clear();
  config.allowedKeyManagement.clear();
  config.allowedPairwiseCiphers.clear();
  config.allowedProtocols.clear();
  config.SSID = "\"" + SSID + "\"";
  // nopass
  if (Type == WifiCipherType.WIFICIPHER_NOPASS) {
   config.wepKeys[0] = "";
   config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
   config.wepTxKeyIndex = 0;
  }
  // wep
  if (Type == WifiCipherType.WIFICIPHER_WEP) {
   if (!TextUtils.isEmpty(Password)) {
    if (isHexWepKey(Password)) {
     config.wepKeys[0] = Password;
    } else {
     config.wepKeys[0] = "\"" + Password + "\"";
    }
   }
   config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
   config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
   config.allowedKeyManagement.set(KeyMgmt.NONE);
   config.wepTxKeyIndex = 0;
  }
  // wpa
  if (Type == WifiCipherType.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;
 }

 // 打开wifi功能
 private boolean openWifi() {
  boolean bRet = true;
  if (!wifiManager.isWifiEnabled()) {
   bRet = wifiManager.setWifiEnabled(true);
  }
  return bRet;
 }
    //启动一个新线程打开wifi
 class ConnectRunnable implements Runnable {
  private String ssid;

  private String password;

  private WifiCipherType type;

  public ConnectRunnable(String ssid, String password, WifiCipherType type) {
   this.ssid = ssid;
   this.password = password;
   this.type = type;
  }

  @Override
  public void run() {
   // 打开wifi
   openWifi();
   // 开启wifi功能需要一段时间(我在手机上测试一般需要1-3秒左右),所以要等到wifi
   // 状态变成WIFI_STATE_ENABLED的时候才能执行下面的语句
   while (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
    try {
     // 为了避免程序一直while循环,让它睡个100毫秒检测……
     Thread.sleep(100);
    } catch (InterruptedException ie) {
    }
   }

   WifiConfiguration wifiConfig = createWifiInfo(ssid, password, type);
   //
   if (wifiConfig == null) {
    Log.d(TAG, "wifiConfig is null!");
    return;
   }

   WifiConfiguration tempConfig = isExsits(ssid);

   if (tempConfig != null) {
    wifiManager.removeNetwork(tempConfig.networkId);
   }

   int netID = wifiManager.addNetwork(wifiConfig);
   boolean enabled = wifiManager.enableNetwork(netID, true);
   Log.d(TAG, "enableNetwork status enable=" + enabled);
   boolean connected = wifiManager.reconnect();
   Log.d(TAG, "enableNetwork connected=" + connected);
  }
 }

 private static boolean isHexWepKey(String wepKey) {
  final int len = wepKey.length();

  // WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
  if (len != 10 && len != 26 && len != 58) {
   return false;
  }

  return isHex(wepKey);
 }

 private static boolean isHex(String key) {
  for (int i = key.length() - 1; i >= 0; i--) {
   final char c = key.charAt(i);
   if (!(c >= ‘0‘ && c <= ‘9‘ || c >= ‘A‘ && c <= ‘F‘ || c >= ‘a‘
     && c <= ‘f‘)) {
    return false;
   }
  }

  return true;
 }

}

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。