基于android的wifi模块功能开发教程

编程实验

72人已加入

描述

  Android平台下的WIFI模块功能

  1.开关WIFI

  除了在WIFI设置界面可以开关WIFI,还有其他的方法可以设置,要查看这些开关状态是否一致。还有就是飞行模式对WIFI开关的影响,由于WIFI开和关都有一个时间过程,而飞行模式的开关瞬间完成,所以有时会出现冲突。

  2.开关新可用网络提醒

  新可用网络的定义是自WIFI模块开启后,从未发现过的,为加密的网络。只有满足了新可用网络的定义,才会有提醒。

  3.连接断开网络

  连接断开各种不同加密类型的网络(具体类型下文有详解)

  4.手动添加网络

  需要路由器关闭SIID广播。可手动输入SIID,网络加密类型,密码。对于OPAL手机来说,路由器隐藏了SSID,手动添加的网络是无法连接的。

  5.搜索网络

  手动点击搜索按钮可以搜索网络,也可以等待WIFI模块自动搜索网络。

  6.休眠设置

  由于WIFI模块是用电大户,所有为了省电,Android的WIFI加了一个休眠策略,可以设置永远不断开,充电时不断开和锁屏时断开。要测试休眠设置是否有效,可以在路由器上PING手机的IP,PING通就是连接状态。OPAL手机的休眠策略属于完全失效,现在的情况是无论选哪个都会一直保持连接,锁屏后15分钟再休眠。

  7.设置静态IP

  Android系统里对IP设置的输入限制很有问题,我一直认为这是弱智的限制。正常IP的范围在0-255之间,android对IP输入的限制是整数0到整数255之间,也就是说0000.000200.001.001这样一个IP都能合法输入。

  热点加密类型

  目前,常见及需要处理的热点,包括以下3大类:

  open——开放型网络,即无加密,可直接连接

  wep——采用wep加密类型的热点,已过时,不安全,容易被破解,目前使用率已不足10%

  wpa/wpa2——目前使用最广泛,相对最安全,破解难度最大的加密类型

  wps(wifiprotectedsetup):是为了进一步增强wpa热点及简化连接过程的技术,不属于加密类型。

  android的wifi模块功能开发教程

  1、获取WifiManager入口类实例

  wifiManager = (WifiManager) context

  .getSystemService(Context.WIFI_SERVICE);12

  2、打开及关闭wifi

  wifiManager.setWifiEnabled(true)1

  true表示打开wifi开关,false表示关闭,该方法的返回值仅代表操作是否成功,不代表wifi状态的变化;

  通过监听广播WifiManager.WIFI_STATE_CHANGED_ACTION ,来判断真正的wifi开关变化,该广播带有一个int型的值来表示wifi状态:

  int wifistate = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,

  WifiManager.WIFI_STATE_DISABLED);

  switch (wifistate) {

  case WifiManager.WIFI_STATE_DISABLED:

  //wifi已关闭

  break;

  case WifiManager.WIFI_STATE_ENABLED:

  //wifi已打开

  break;

  case WifiManager.WIFI_STATE_ENABLING:

  //wifi正在打开

  break;

  default:

  break;

  }123456789101112131415

  可以看到,该操作其实是一个异步操作,一般耗时在1~3秒之间。

  3、周围热点扫描

  wifiManager.startScan()1

  以上方法为开始扫描的接口,其返回值代表操作是否成功,扫描结果通过另外一个接口获取:

  List《ScanResult》 results = wifiManager.getScanResults();1

  一般在主动调用startScan之后,大概2秒左右,会收到WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)广播通知,该广播包括一个boolean型的额外参数:

  boolean isScanned = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true);1

  上面的值表示,扫描结果是否已可用,若可用,则可以使用getScanResults获取结果,在结果没有就绪之前,会返回null。

  一般系统本身会调用startScan接口,而该操作相对比较耗电,因此在应用中要酌情使用,并不需要频繁调用。

  4、获取已连接过的热点

  所有已经连接过的热点,都会存在本地一个文件中,一般路径为/data/misc/wifi/wpa_supplicant.conf(查看需root),而在程序中获取则通过以下接口:

  List《WifiConfiguration》 configurations = wifiManager.getConfiguredNetworks();1

  获取到的WiFiConfiguration对象中,只有ssid和networkId是一定有的,可以用于直接连接该热点,其他信息如bssid,密钥等信息基本都是空的。(如何直接连接热点,下文叙述)

  5、获取当前wifi连接信息

  WifiInfo info = wifiManager.getConnectionInfo();1

  该对象代表当前已连接的热点,信息,无连接时返回null;

  该对象可获取包括ssid,bssid,networkId等信息,而ssid是包括了双引号的,如“CCMC”,在之前的扫描结果ScanResult中,ssid并不带双引号。

  6、连接指定热点

  连接一个未连接过的热点时,需3步:

  1)创建一个配置:WifiConfiguration

  public WifiConfiguration createConfiguration(AccessPoint ap) {

  String SSID = ap.getSsid();

  WifiConfiguration config = new WifiConfiguration();

  config.SSID = “”“ + SSID + ”“”;

  String encryptionType = ap.getEncryptionType();

  String password = ap.getPassword();

  if (encryptionType.contains(“wep”)) {

  /**

  * special handling according to password length is a must for wep

  */

  int i = password.length();

  if (((i == 10 || (i == 26) || (i == 58))) && (password.matches(“[0-9A-Fa-f]*”))) {

  config.wepKeys[0] = password;

  } else {

  config.wepKeys[0] = “”“ + password + ”“”;

  }

  config.allowedAuthAlgorithms

  .set(WifiConfiguration.AuthAlgorithm.SHARED);

  config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

  config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

  config.wepTxKeyIndex = 0;

  } else if (encryptionType.contains(“wpa”)) {

  config.preSharedKey = “”“ + password + ”“”;

  config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

  } else {

  config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

  }

  return config;

  }123456789101112131415161718192021222324252627282930

  *网上流传多处创建configuration的代码,但大都未经过验证,以上代码已经经过了线上版本测试,准确可用。

  判断加密类型的方式,可以优化,本处仅示例。*

  2)生成一个networkId

  WifiConfiguration config = createConfiguration(ap);

  /**

  * networkId is bigger than 0 in most time, 0 in few time and smaller than 0 in no time

  */

  int networkId = networkId = wifiManager.addNetwork(config);123456

  一般情况下,对一个已经连接过的热点(本地有连接记录),进行以上操作时,在api21及以上会返回一个小于0的networkId,此时,进行下一步连接是没有意义的,获得一个小于0的networkId已经表示连接失败。

  3)开始连接

  wifiManager.enableNetwork(networkId, true)1

  对于已经连接过的热点,通过小项4 中的方式,获取到该热点的networkId之后,可直接进行第三步的连接,无需1)2);

  若有必要进行12步(如尝试一个新密码,因为即使使用了错误的密码连接,系统还是会为本次连接生成一个本地记录),则必须在一开始,将本地记录remove掉,remove操作将在下文介绍。

  连接结果通过两个广播反馈:WifiManager.NETWORK_STATE_CHANGED_ACTION和WifiManager.SUPPLICANT_STATE_CHANGED_ACTION

  其中,密码错误的结果通知需通过第二个广播判断:

  int error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0);

  if (WifiManager.ERROR_AUTHENTICATING == error) {

  //密码错误,认证失败

  }1234

  其他结果均通过第一个广播接收:

  if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {

  NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

  if (null != info) {

  NetworkInfo.DetailedState state = info.getDetailedState();

  }

  }123456

  public enum DetailedState {

  /** Ready to start data connection setup. */

  IDLE,

  /** Searching for an available access point. */

  SCANNING,

  /** Currently setting up data connection. */

  CONNECTING,

  /** Network link established, performing authentication. */

  AUTHENTICATING,

  /** Awaiting response from DHCP server in order to assign IP address information. */

  OBTAINING_IPADDR,

  /** IP traffic should be available. */

  CONNECTED,

  /** IP traffic is suspended */

  SUSPENDED,

  /** Currently tearing down data connection. */

  DISCONNECTING,

  /** IP traffic not available. */

  DISCONNECTED,

  /** Attempt to connect failed. */

  FAILED,

  /** Access to this network is blocked. */

  BLOCKED,

  /** Link has poor connectivity. */

  VERIFYING_POOR_LINK,

  /** Checking if network is a captive portal */

  CAPTIVE_PORTAL_CHECK

  }12345678910111213141516171819202122232425262728

  7、断开当前wifi连接

  wifiManager.disconnect()1

  以上接口返回值代表当前操作是否成功,操作的最终结果,会在两个广播中有所反馈:

  WifiManager.SUPPLICANT_STATE_CHANGED_ACTION

  WifiManager.NETWORK_STATE_CHANGED_ACTION

  并且断开成功的广播会发送若干次。

  8、遗忘一个已连接过的热点

  boolean isRemoved = wifiManager.removeNetwork(networkId)1

  返回值代表操作是否成功,该操作在api21以上的系统中,成功率在10%以下,在api21以下,基本都可以成功;

  可以通过反复进行此操作来提高成功率,但效果不大。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分