前言

    此篇博客讲解WiFi正常功能开发与热点功能开发

权限

不管是WiFi正常功能还是WiFi热点都需要以下权限,Android5.0还需要动态权限

  1.  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  2. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  3. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  4. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

WiFi正常功能(扫描/连接/断开)

初始化WiFi管理

操作WiFi的基础类,所有的WiFi操作都需要使用这个管理类

  1. WifiManager mWifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);

判断WiFi状态

这个是判断设备的WiFi硬件状态,一共有已经几种设备状态:

WIFI_STATE_DISABLED    WiFi已经禁用
WIFI_STATE_DISABLING     正在禁用WiFi中
WIFI_STATE_ENABLED     WiFi已经启用
WIFI_STATE_ENABLING      正在启用WiFi中
WIFI_STATE_UNKNOWN      设备状态未知(或者没有WiFi硬件支持)

  1. if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED){
  2. Log.e(TAG, "WiFi已经启用");
  3. }

判断WiFi是否开启

这是官方提供的更快捷判断WiFi是否开启的方法

  1. if (mWifiManager.isWifiEnabled()){
  2. Log.e(TAG, "WiFi已经开启");
  3. }else {
  4. Log.e(TAG, "WiFi已经关闭");
  5. }

开启或者关闭WiFi

用此方法开启WiFi会有一个系统弹窗提示用户手动开启WiFi.

  1. mWifiManager.setWifiEnabled(true); //false为关闭

搜索WiFi与获取WiFi设备列表

  1. private void scan(){
  2. mWifiManager.startScan(); //搜索WiFi,在这个代码的注释里有说明搜索过程是异步的
  3. Handler handler = new Handler();
  4. handler.postDelayed(new Runnable() {
  5. @Override
  6. public void run() {
  7. List<ScanResult> list = mWifiManager.getScanResults(); //获取WiFi列表
  8. for (ScanResult scanResult : list){
  9. Log.e(TAG, "==================================");
  10. Log.e(TAG, "scan: wifi 名称="+scanResult.SSID);
  11. Log.e(TAG, "scan: wifi WiFi地址="+scanResult.BSSID);
  12. Log.e(TAG, "scan: wifi 加密方式="+scanResult.capabilities);
  13.  
  14. }
  15. }
  16. },1000);
  17. }

开始搜索是一个异步的过程,你可以直接获取WiFi列表(有可能还是上次的搜索结果),也可以写个Handler等待几秒在获取WiFi列表.

注意一! mWifiManager.getScanResults() 得到的List里面的数据其实是一直会变化的! 意思是计算你获取到了这个list,在WiFi的底层代码里依然会修改/增加/删除这个list里的数据

注意二! mWifiManager.getScanResults() 得到的List里面的数据会出现重复/空名/个别值为null的问题,这是正常的.所以WiFi的难点不是连接与搜索,而是清洗数据

结果:

  1. WifiActivity: ==================================
  2. WifiActivity: scan: wifi 名称=WETOOL_2.4G
  3. WifiActivity: scan: wifi WiFi地址=08:9b:4b:9d:25:b5
  4. WifiActivity: scan: wifi 加密方式=[WPA2-PSK+FT/PSK-CCMP][ESS]
  5. WifiActivity: ==================================
  6. WifiActivity: scan: wifi 名称=2_5g
  7. WifiActivity: scan: wifi WiFi地址=d0:ee:07:59:64:18
  8. WifiActivity: scan: wifi 加密方式=[WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS]
  9. WifiActivity: ==================================
  10. WifiActivity: scan: wifi 名称=喵星人的WiFi
  11. WifiActivity: scan: wifi WiFi地址=6c:88:14:f4:f3:5d
  12. WifiActivity: scan: wifi 加密方式=[WPA2-PSK-CCMP][ESS]

ScanResult可以获取的信息

ScanResult是搜索到WiFi列表后获取的单个WiFi信息,里面包含了一些信息需要了解一下(注意,如果你看源码会发现有很多信息是隐藏的无法调用的.那些变量都是系统级别的API才能调用,这里只说明可以看到的信息)

  1. CharSequence area = scanResult.venueName; //WiFi接入点的地点名称
  2. int frequency = scanResult.frequency; //频率
  3. long refreshTime = scanResult.timestamp; //此WiFi最新的刷新时间戳
  4. int level = scanResult.level; //信号强度
  5. String encryption = scanResult.capabilities;//加密方式 例如:WEP/WAP/WAP2
  6. String address = scanResult.BSSID; //WiFi的地址
  7. String name = scanResult.SSID; //WiFi的名称

连接指定的WIiFi网络

这段流程比较长,大致是这样的:

1.搜索WiFi,找到指定WiFi 获取名称/地址/加密方式,以及你自己知道的WiFi密码

2.创建WiFi配置信息WifiConfiguration, 添加WiFi名称,地址

3.在根据加密方式以对应的方式添加密码到WifiConfiguration

4.将WiFi配置WifiConfiguration,添加到以配置的网络列表里addNetwork(wifiConfiguration);

5.获取已经配置好的网络列表mWifiManager.getConfiguredNetworks();,找到指定WiFi,获取id

6.断开现在正在连接的WiFi,输入id启用设置好的WiFi,重新连接

注意! scanResult.BSSID  这个BSSID其实动态生成的路由地址,不可以依靠这来判断wifi的唯一性. 所以用SSID加BSSID来锁定一个WiFi是不现实的.因为有时候BSSID其实是null的.只能使用SSID来判断WiFi,遇到重名WiFi没有什么办法

  1. public void scan(){
  2. List<ScanResult> list = mWifiManager.getScanResults(); //获取WiFi列表
  3. Log.e(TAG, "list 长度="+list.size());
  4. for (ScanResult scanResult : list){
  5. if (scanResult.SSID.equals("My_5g")){ //找到我们需要的WiFi
  6. connectionWifi(scanResult.SSID,"winteam0901", scanResult.capabilities); //连接它
  7. }
  8.  
  9. }
  10. }
  11.  
  12. /**
  13. * 连接WiFi的方法
  14. * @param ssid wifi名称
  15. * @param password WiFi密码
  16. * @param capabilities 加密方式
  17. */
  18. public void connectionWifi(String ssid, String password, String capabilities) {
  19. WifiConfiguration wifiConfiguration = new WifiConfiguration();
  20. ssid = "\"" + ssid + "\""; //WiFi的名称配置需要加引号
  21. password = "\"" + password + "\""; //WiFi的密码配置需要加引号
  22. wifiConfiguration.SSID = ssid;
  23. if (capabilities.contains("WPA")) {
  24. wifiConfiguration.preSharedKey = password;
  25.  
  26. } else if (capabilities.contains("WEP")) {
  27. wifiConfiguration.wepKeys[0] = password;
  28. wifiConfiguration.wepTxKeyIndex = 0;
  29. wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
  30. wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
  31.  
  32. } else if (capabilities.contains("OPEN")) {
  33. wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
  34.  
  35. }
  36. mWifiManager.addNetwork(wifiConfiguration);
  37. List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
  38. for (WifiConfiguration item : wifiConfigurationList) {
  39. if (item.SSID == null) {
  40. continue;
  41. }
  42. if (item.SSID.equals(ssid)) {
  43. mWifiManager.disconnect(); //断开连接
  44. mWifiManager.enableNetwork(item.networkId, true); //连接我们需要的WiFi
  45. mWifiManager.reconnect(); //重新连接
  46. }
  47. }
  48. }

获取已经配置密码并且保存的WiFi网络列表

上面的代码里有说明获取已经配置密码的WiFi网络列表的部分代码了,就是如下代码,但是这里在强调一下.他的使用情景与信息

1.WiFi是有暂存的,以记录密码的WiFi系统会保存起来,方便某个WiFi断开后自动重新连接这个配置列表里的其他WiFi

2.所以在如果要删除某个WiFi,你必需移除这个配置列表里的这个WiFi,如果只是断开操作将可能自动重连

3.这个配置列表还能告诉用户已经保存连接过所有WiFi的,用户直接点击后重新连接这个WiFi(不需要再次输入密码)

4.你可以重新更新这个配置列表的WiFi密码

注意! 跟上面的一样 mWifiManager.getConfiguredNetworks() 得到的List里面的数据会出现重复/空名/个别值为null的问题.另外这里获取的WiFi数据是不含信号强度的.如果你需要信号强度就需要跟ScanResult数据进行对比后获取.

  1. List<WifiConfiguration> configurationList = mWifiManager.getConfiguredNetworks();

更新指定WiFi(更换密码)

更新WiFi的方法主要是mWifiManager.updateNetwork(item);  但是请注意这个WiFi必须是已经保存配置的WiFi

  1.   /**
  2. * 更新WiFi
  3. */
  4. public void undateWifi(String ssid, String password) {
  5. List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
  6. for (WifiConfiguration item : wifiConfigurationList) {
  7. if (item.SSID == null) {
  8. continue;
  9. }
  10. if (item.SSID.equals("\"" + ssid + "\"")) {
  11. item.preSharedKey = "\"" + password + "\"";
  12. mWifiManager.disconnect();
  13. int id = mWifiManager.updateNetwork(item);
  14. if (id == -1) { //id如果等于 -1 就说明更新失败了
  15. return;
  16. }
  17. mWifiManager.enableNetwork(id, true); //启用连接WiFi
  18. mWifiManager.reconnect();
  19. }
  20. }
  21. }

移除指定WiFi

 注意! 这里的移除WiFi,只能移除自己的app保存的WiFi,如果是手机-设置-WiFi设置里手动添加的WiFi,你是无法移除的.

  1.   /**
  2. * 移除这个app保存的WiFi
  3. *
  4. * @param ssid
  5. */
  6. public void removeWifi(String ssid) {
  7. mWifiManager.startScan();
  8. List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
  9. for (WifiConfiguration item : wifiConfigurationList) {
  10. if (item.SSID.equals("\"" + ssid + "\"")) {
  11. mWifiManager.disconnect();
  12. mWifiManager.removeNetwork(item.networkId);
  13. mWifiManager.reconnect();
  14.  
  15. }
  16. }
  17. }

获取当前正在连接中的WiFi信息

  1. public WifiInfo getConnectionInfo() {
  2. WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
  3. wifiInfo.getSSID();//WiFi名称
  4. wifiInfo.getRssi();//信号强度
  5. wifiInfo.getIpAddress();//ip地址
  6. wifiInfo.getFrequency();//频率 比如2.4G(boolean is24G = frequency > 2400 && frequency < 2500;) 或者 5G (boolean is5G = frequency > 4900 && frequency < 5900;)的WiFi
  7. wifiInfo.getNetworkId();//id
  8. wifiInfo.getLinkSpeed();//网络链接速度
  9. wifiInfo.getSupplicantState();//获取请求状态
  10. return wifiInfo;
  11. }

  这里获取的ssid 是带引号的

  注意!获取正在连接中的WiFiInfo,这个数据是永远不会是空的,如果一次WiFi都没连接过那么它携带的数据会有空的,如果连接过然后又断开了,那么你在这里获取的就是之前连接的WiFi. 那么如何判断当前是否真的有连接WiFi呢?

很简单判断ip地址即可,这个地址是实时刷新的:

  1. if (wifiInfo.getIpAddress() == 0){
  2. Log.e(TAG, "getData: 当前未连接WiFi");
  3. }

增加引号和移除引号的方法

  1. /**
  2. * 移除引号
  3. *
  4. * @param content
  5. * @return
  6. */
  7. public String removeQuotationMarks(String content) {
  8. content = content.substring(1, content.length() - 1);
  9. return content;
  10.  
  11. }
  12.  
  13. /**
  14. * 添加引号
  15. *
  16. * @param content
  17. * @return
  18. */
  19. public String addQuotationMarks(String content) {
  20. content = "\"" + content + "\"";
  21. return content;
  22. }

格式化wifi信号值

  1. /**
  2. * WifiInfo.MIN_RSSI = -126;
  3. * WifiInfo.MAX_RSSI = 200;
  4. *
  5. * Quality Excellent Good Fair Poor
  6. * dBm -30 ~ -61 -63 ~ -73 -75 ~ -85 -87 ~ -97
  7. *
  8. * @param rssi
  9. * @return
  10. */
  11. public static int formatLevel(int rssi) {
  12. if (rssi < -97){
  13. return 0;
  14. }else if (rssi < -87){
  15. return 1;
  16. }else if (rssi < -75){
  17. return 2;
  18. }else if (rssi < -63){
  19. return 3;
  20. }else {
  21. return 4;
  22. }
  23. }

将WiFi的IP地址转换成Mac地址显示

  1. /**
  2. * 将idAddress转化成string类型的Id字符串
  3. *
  4. * @param idString
  5. * @return
  6. */
  7. private static String getStringId(int idString) {
  8. StringBuffer sb = new StringBuffer();
  9. int b = (idString >> 0) & 0xff;
  10. sb.append(b + ".");
  11. b = (idString >> 8) & 0xff;
  12. sb.append(b + ".");
  13. b = (idString >> 16) & 0xff;
  14. sb.append(b + ".");
  15. b = (idString >> 24) & 0xff;
  16. sb.append(b);
  17. return sb.toString();
  18. }

获取WiFi状态

注册广播

  1. mIntentFilter = new IntentFilter();
  2. mIntentFilter.addAction("android.net.wifi.STATE_CHANGE");//WiFi状态变化
  3. mIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");//WiFi开关状态
  4. mWiFiChangeReceiver = new WiFiChangeReceiver();
  5. registerReceiver(mWiFiChangeReceiver,mIntentFilter);

接收广播处理

  1. class WiFiChangeReceiver extends BroadcastReceiver{
  2.  
  3. @Override
  4. public void onReceive(Context context, Intent intent) {
  5.  
  6. if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
  7. int switchState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);//得到WiFi开关状态值
  8. switch (switchState) {
  9. case WifiManager.WIFI_STATE_DISABLED://WiFi已关闭
  10. WiFIStateData data1 = new WiFIStateData();
  11. data1.time = mDf.format(System.currentTimeMillis());
  12. data1.state = "WiFi关闭";
  13. mDao.insert(data1);
  14. EventBus.getDefault().post(msgData);
  15. Log.e(TAG, "WiFi关闭");
  16. break;
  17. case WifiManager.WIFI_STATE_DISABLING://WiFi关闭中
  18. Log.e(TAG, "WiFi关闭中");
  19. break;
  20. case WifiManager.WIFI_STATE_ENABLED://WiFi已开启
  21. WiFIStateData data2 = new WiFIStateData();
  22. data2.time = mDf.format(System.currentTimeMillis());
  23. data2.state = "WiFi开启";
  24. mDao.insert(data2);
  25. EventBus.getDefault().post(msgData);
  26. Log.e(TAG, "WiFi开启");
  27. break;
  28. case WifiManager.WIFI_STATE_ENABLING://WiFi开启中
  29. Log.e(TAG, "WiFi开启中");
  30. break;
  31. case WifiManager.WIFI_STATE_UNKNOWN://WiFi状态未知
  32. WiFIStateData data3 = new WiFIStateData();
  33. data3.time = mDf.format(System.currentTimeMillis());
  34. data3.state = "WiFi状态未知";
  35. mDao.insert(data3);
  36. EventBus.getDefault().post(msgData);
  37. Log.e(TAG, "WiFi状态未知");
  38. break;
  39. default:
  40. break;
  41. }
  42. }
  43.  
  44. if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){ //网络状态改变行为
  45. Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);//得到信息包
  46. if (parcelableExtra != null){、蓝牙——
  47. NetworkInfo networkInfo = (NetworkInfo)parcelableExtra;//得到网络信息
  48. NetworkInfo.DetailedState detailedState = networkInfo.getDetailedState();
  49. switch (detailedState){
  50. case CONNECTED:
  51. mDisconnectState = true;
  52. WiFIStateData data4 = new WiFIStateData();
  53. data4.time = mDf.format(System.currentTimeMillis());
  54. data4.state = "已经连接";
  55. mDao.insert(data4);
  56. EventBus.getDefault().post(msgData);
  57. Log.e(TAG, "已经连接");
  58. break;
  59. case DISCONNECTED:
  60. if (mDisconnectState){
  61. mDisconnectState = false;
  62. WiFIStateData data5 = new WiFIStateData();
  63. data5.time = mDf.format(System.currentTimeMillis());
  64. data5.state = "已经断开";
  65. mDao.insert(data5);
  66. EventBus.getDefault().post(msgData);
  67. Log.e(TAG, "已经断开");
  68. }
  69. break;
  70. case IDLE:
  71.  
  72. WiFIStateData data6 = new WiFIStateData();
  73. data6.time = mDf.format(System.currentTimeMillis());
  74. data6.state = "空闲中";
  75. mDao.insert(data6);
  76. EventBus.getDefault().post(msgData);
  77. Log.e(TAG, "空闲中");
  78.  
  79. break;
  80. case AUTHENTICATING:
  81.  
  82. WiFIStateData data7 = new WiFIStateData();
  83. data7.time = mDf.format(System.currentTimeMillis());
  84. data7.state = "认证中";
  85. mDao.insert(data7);
  86. EventBus.getDefault().post(msgData);
  87. Log.e(TAG, "认证中");
  88.  
  89. break;
  90. case BLOCKED:
  91.  
  92. WiFIStateData data8 = new WiFIStateData();
  93. data8.time = mDf.format(System.currentTimeMillis());
  94. data8.state = "认证失败";
  95. mDao.insert(data8);
  96. EventBus.getDefault().post(msgData);
  97. Log.e(TAG, "认证失败");
  98.  
  99. break;
  100. case CAPTIVE_PORTAL_CHECK:
  101.  
  102. WiFIStateData data9 = new WiFIStateData();
  103. data9.time = mDf.format(System.currentTimeMillis());
  104. data9.state = "连接检查";
  105. mDao.insert(data9);
  106. EventBus.getDefault().post(msgData);
  107. Log.e(TAG, "连接检查");
  108.  
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114.  
  115. }
  116.  
  117. }
  118. }

WiFi设备信息的数据清洗

  上面的WiFi内容都是WiFi基本玩法,下面才是玩自定义WiFi的难点。  

  Android提供的WiFi框架会因为WiFi设备原因,显示很多同名WiFi。并且getConfiguredNetworks 与  getConnectionInfo 与 getScanResults 三种数据获取后都有相同的数据,数据比较混乱重复,甚至还有空名称的WiFi。所以,我们需要清洗它,这是自定义WiFi功能的难点。

1.创建一个清洗后数据保存的bean

  1. package com.zh.zwifidemo.wifi;
  2.  
  3. import java.util.List;
  4.  
  5. public class WifiDataBean {
  6. private ConnectionWifi connectionWifi; //当前正在连接的WiFi
  7. private List<ConfigWifi> configWifiList;//已经配置过的WiFi
  8. private List<OtherWifi> otherWifiList; //搜索到的其他WiFi
  9.  
  10. public ConnectionWifi getConnectionWifi() {
  11. return connectionWifi;
  12. }
  13.  
  14. public void setConnectionWifi(ConnectionWifi connectionWifi) {
  15. this.connectionWifi = connectionWifi;
  16. }
  17.  
  18. public List<ConfigWifi> getConfigWifiList() {
  19. return configWifiList;
  20. }
  21.  
  22. public void setConfigWifiList(List<ConfigWifi> configWifiList) {
  23. this.configWifiList = configWifiList;
  24. }
  25.  
  26. public List<OtherWifi> getOtherWifiList() {
  27. return otherWifiList;
  28. }
  29.  
  30. public void setOtherWifiList(List<OtherWifi> otherWifiList) {
  31. this.otherWifiList = otherWifiList;
  32. }
  33.  
  34. public class ConnectionWifi{
  35. private String ssid;
  36. private Integer level; //信号强度
  37. private Integer ipAddress;
  38. private Integer frequency;//频率
  39.  
  40. public String getSsid() {
  41. return ssid;
  42. }
  43.  
  44. public void setSsid(String ssid) {
  45. this.ssid = ssid;
  46. }
  47.  
  48. public Integer getLevel() {
  49. return level;
  50. }
  51.  
  52. public void setLevel(Integer level) {
  53. this.level = level;
  54. }
  55.  
  56. public Integer getIpAddress() {
  57. return ipAddress;
  58. }
  59.  
  60. public void setIpAddress(Integer ipAddress) {
  61. this.ipAddress = ipAddress;
  62. }
  63.  
  64. public Integer getFrequency() {
  65. return frequency;
  66. }
  67.  
  68. public void setFrequency(Integer frequency) {
  69. this.frequency = frequency;
  70. }
  71. }
  72.  
  73. public class ConfigWifi{
  74. private String ssid;
  75. private Integer level; //信号强度
  76. /*
  77. public static final int CURRENT = 0; 已连接
  78. public static final int DISABLED = 1; 停用,错误密码
  79. public static final int ENABLED = 2; 已保存,未连接
  80. */
  81. private Integer state;
  82. private String capabilities;
  83.  
  84. public String getSsid() {
  85. return ssid;
  86. }
  87.  
  88. public void setSsid(String ssid) {
  89. this.ssid = ssid;
  90. }
  91.  
  92. public Integer getLevel() {
  93. return level;
  94. }
  95.  
  96. public void setLevel(Integer level) {
  97. this.level = level;
  98. }
  99.  
  100. public Integer getState() {
  101. return state;
  102. }
  103.  
  104. public void setState(Integer state) {
  105. this.state = state;
  106. }
  107.  
  108. public String getCapabilities() {
  109. return capabilities;
  110. }
  111.  
  112. public void setCapabilities(String capabilities) {
  113. this.capabilities = capabilities;
  114. }
  115. }
  116.  
  117. public class OtherWifi{
  118. private String ssid;
  119. private Integer level; //信号强度
  120. private String capabilities;//安全形式
  121.  
  122. public String getSsid() {
  123. return ssid;
  124. }
  125.  
  126. public void setSsid(String ssid) {
  127. this.ssid = ssid;
  128. }
  129.  
  130. public Integer getLevel() {
  131. return level;
  132. }
  133.  
  134. public void setLevel(Integer level) {
  135. this.level = level;
  136. }
  137.  
  138. public String getCapabilities() {
  139. return capabilities;
  140. }
  141.  
  142. public void setCapabilities(String capabilities) {
  143. this.capabilities = capabilities;
  144. }
  145. }
  146.  
  147. }

  2.清洗将所有获取的WiFi数据清洗,最后返回我们需要的bean数据

  1. public WifiDataBean getWifiBean() {
  2. WifiDataBean wifiDataBean = new WifiDataBean();
  3. WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
  4. List<ScanResult> scanResultList = new ArrayList<>();
  5. List<WifiConfiguration> configurationList = new ArrayList<>();
  6. scanResultList.addAll(mWifiManager.getScanResults());
  7. configurationList.addAll(mWifiManager.getConfiguredNetworks());
  8.  
  9. List<WifiDataBean.ConfigWifi> configWifiList = new ArrayList<>();
  10. List<WifiDataBean.OtherWifi> otherWifiList = new ArrayList<>();
  11.  
  12. /*
  13. 处理当前正在连接中的WiFi
  14. */
  15. if (wifiInfo.getIpAddress() == 0) {
  16. wifiDataBean.setConnectionWifi(null);
  17. } else {
  18. WifiDataBean.ConnectionWifi connectionWifi = wifiDataBean.new ConnectionWifi();
  19. connectionWifi.setSsid(wifiInfo.getSSID());
  20. connectionWifi.setLevel(wifiInfo.getRssi());
  21. connectionWifi.setIpAddress(wifiInfo.getIpAddress());
  22. connectionWifi.setFrequency(wifiInfo.getFrequency());
  23. wifiDataBean.setConnectionWifi(connectionWifi);
  24. }
  25.  
  26. /*
  27. 处理已经配置过的WiFi
  28. */
  29. if (configurationList.isEmpty()) {
  30. wifiDataBean.setConfigWifiList(configWifiList);
  31.  
  32. } else {
  33. for (int i = 0; i < configurationList.size(); i++) { //除去null的WiFi
  34. WifiConfiguration configuration = configurationList.get(i);
  35. if (configuration.SSID == null) {
  36. configurationList.remove(configuration);
  37. }
  38. }
  39.  
  40. if (wifiDataBean.getConnectionWifi() != null) {
  41. for (int i = 0; i < configurationList.size(); i++) { //去除正在连接的WiFi item
  42. WifiConfiguration configuration = configurationList.get(i);
  43. if (configuration.SSID.equals(wifiDataBean.getConnectionWifi().getSsid())) {
  44. configurationList.remove(configuration);
  45. }
  46. }
  47. }
  48.  
  49. for (int i = 0; i < configurationList.size(); i++) { //除去重复的WiFi
  50. WifiConfiguration configuration = configurationList.get(i);
  51. for (int j = i + 1; j < configWifiList.size(); j++) {
  52. WifiConfiguration item = configurationList.get(j);
  53. if (configuration.SSID.equals(item.SSID)) {
  54. configurationList.remove(item);
  55. }
  56.  
  57. }
  58. }
  59.  
  60. for (int i = 0; i < configurationList.size(); i++) { //添加配置过的WiFi数据
  61. WifiConfiguration configuration = configurationList.get(i);
  62. WifiDataBean.ConfigWifi configWifi = wifiDataBean.new ConfigWifi();
  63. configWifi.setSsid(configuration.SSID);
  64. configWifi.setState(configuration.status);
  65. for (int j = 0; j < scanResultList.size(); j++) {
  66. ScanResult scanResult = scanResultList.get(j);
  67. if (removeQuotationMarks(configuration.SSID).equals(scanResult.SSID)) {
  68. configWifi.setLevel(scanResult.level);
  69. }
  70. }
  71. if (configWifi.getLevel() == null) {
  72. configWifi.setLevel(-98);
  73.  
  74. }
  75. if (configuration.preSharedKey != null && !configuration.preSharedKey.equals("")) {
  76. configWifi.setCapabilities("WPA");
  77. } else if (configuration.wepKeys[0] != null && !configuration.wepKeys[0].equals("")) {
  78. configWifi.setCapabilities("WEP");
  79. } else {
  80. configWifi.setCapabilities("OPEN");
  81. }
  82. configWifiList.add(configWifi);
  83. }
  84. wifiDataBean.setConfigWifiList(configWifiList);
  85. }
  86.  
  87. /*
  88. 设置其他WiFi
  89. */
  90. if (scanResultList.isEmpty()) {
  91. wifiDataBean.setOtherWifiList(otherWifiList);
  92.  
  93. } else {
  94. for (int i = 0; i < scanResultList.size(); i++) { //去除null
  95. ScanResult scanResult = scanResultList.get(i);
  96. if (scanResult.SSID == null) {
  97. scanResultList.remove(scanResult);
  98. }
  99. }
  100.  
  101. if (wifiDataBean.getConnectionWifi() != null){
  102. for (int i = 0; i < scanResultList.size(); i++) { //去除已连接的
  103. ScanResult scanResult = scanResultList.get(i);
  104. if (scanResult.SSID.equals(removeQuotationMarks(wifiDataBean.getConnectionWifi().getSsid()))) {
  105. scanResultList.remove(scanResult);
  106. }
  107. }
  108. }
  109.  
  110. for (int i = 0; i < scanResultList.size(); i++) { //去除已配置的
  111. ScanResult scanResult = scanResultList.get(i);
  112. for (int j = 0; j < configWifiList.size(); j++) {
  113. WifiDataBean.ConfigWifi configWifi = configWifiList.get(j);
  114. if (removeQuotationMarks(configWifi.getSsid()).equals(scanResult.SSID)) {
  115. scanResultList.remove(scanResult);
  116. }
  117. }
  118. }
  119.  
  120. for (int i = 0; i < scanResultList.size(); i++) { //去除重复的
  121. ScanResult scanResult = scanResultList.get(i);
  122. for (int j = i + 1; j < scanResultList.size(); j++) {
  123. ScanResult item = scanResultList.get(j);
  124. if (scanResult.SSID.equals(item.SSID)) {
  125. scanResultList.remove(item);
  126. }
  127. }
  128. }
  129.  
  130. for (int i = 0; i < scanResultList.size(); i++) {
  131. ScanResult scanResult = scanResultList.get(i);
  132. WifiDataBean.OtherWifi otherWifi = wifiDataBean.new OtherWifi();
  133. otherWifi.setSsid(scanResult.SSID);
  134. otherWifi.setLevel(scanResult.level);
  135. otherWifi.setCapabilities(scanResult.capabilities);
  136. otherWifiList.add(otherWifi);
  137. }
  138. wifiDataBean.setOtherWifiList(otherWifiList);
  139. }
  140. return wifiDataBean;
  141. }

WIFI热点

注意WiFi热点除了WiFi权限以外,如果要创建wifi热点还需要一个系统权限 android.permission.WRITE_SETTINGS。

但是这种系统权限在6.0版本后无法直接静态或者动态授权(十分无语)。所以在下面的代码中setPermissions方法就是添加设置权限的办法。

  1. /*
  2. content:创建WiFi热点class
  3. time:2018-7-23 11:23
  4. build:
  5. */
  6.  
  7. public class WiFiAP {
  8. private static WiFiAP mWiFiAP;
  9. private static WifiManager mWifManager;
  10. private WiFiAP(){}
  11.  
  12. public static WiFiAP getI(){
  13. if (mWiFiAP == null){
  14. mWiFiAP = new WiFiAP();
  15. }
  16. return mWiFiAP;
  17. }
  18.  
  19. /**
  20. * 手动得到系统权限的方法,提供给外部启动系统权限界面,以实现手动添加系统权限
  21. * @param context 外部activity的上下文
  22. */
  23. public void setPermissions(Context context){
  24. Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
  25. intent.setData(Uri.parse("package:" + context.getPackageName()));
  26. context.startActivity(intent);
  27.  
  28. }
  29.  
  30. /**
  31. * 打开热点并且创建WiFi热点的方法
  32. * @param context 外部上下文
  33. * @param ssid 要创建WiFi热点的账号名称
  34. * @param password 要创建WiFi热点的密码
  35. * 注意,此方法直接使用WPA2_PSK 的安全策略创建WiFi热点,低版本的Android系统如果需要使用请切换。
  36. */
  37. @SuppressLint("MissingPermission")
  38. public void openWiFiAP(Context context, String ssid, String password){
  39.  
  40. mWifManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
  41.  
  42. if (mWifManager.isWifiEnabled()) {
  43. //如果wifi处于打开状态,则关闭wifi,
  44. mWifManager.setWifiEnabled(false);
  45. }
  46. WifiConfiguration config = new WifiConfiguration();
  47. config.SSID = ssid;
  48. config.preSharedKey = password;
  49. config.hiddenSSID = false;//是否隐藏热点true=隐藏
  50. config.allowedAuthAlgorithms
  51. .set(WifiConfiguration.AuthAlgorithm.OPEN);//开放系统认证
  52. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
  53. int indexOfWPA2_PSK = 4;
  54. //从WifiConfiguration.KeyMgmt数组中查找WPA2_PSK的值
  55. for (int i = 0; i < WifiConfiguration.KeyMgmt.strings.length; i++)
  56. {
  57. if(WifiConfiguration.KeyMgmt.strings[i].equals("WPA2_PSK"))
  58. {
  59. indexOfWPA2_PSK = i;
  60. break;
  61. }
  62. }
  63. //WifiConfiguration.KeyMgmt.WPA_PSK
  64. config.allowedKeyManagement.set(indexOfWPA2_PSK);
  65. config.allowedPairwiseCiphers
  66. .set(WifiConfiguration.PairwiseCipher.TKIP);
  67. config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
  68. config.allowedPairwiseCiphers
  69. .set(WifiConfiguration.PairwiseCipher.CCMP);
  70. config.status = WifiConfiguration.Status.ENABLED;
  71. //通过反射调用设置热点
  72. try {
  73. Method method = mWifManager.getClass().getMethod(
  74. "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
  75. boolean enable = (Boolean) method.invoke(mWifManager, config, true);
  76.  
  77. if (enable) {
  78. Log.e("WiFiAP", "热点已开启 SSID:" + ssid + " Password:"+password);
  79. } else {
  80. Log.e("WiFiAP", "创建热点失败");
  81. }
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. Log.e("WiFiAP", "创建热点失败"+e);
  85. }
  86.  
  87. }
  88.  
  89. /**
  90. * 关闭WiFi热点的方法
  91. * @param context 外部activity的上下文
  92. */
  93. public void closeWiFiAP(Context context){
  94. mWifManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
  95. if( mWifManager == null){
  96. Log.e("closeWiFiAP", "Error: mWifManager is null");
  97. return;
  98. }
  99. try {
  100. Method method = mWifManager.getClass().getMethod("getWifiApConfiguration");
  101. method.setAccessible(true);
  102. WifiConfiguration config = (WifiConfiguration) method.invoke(mWifManager);
  103. Method method2 = mWifManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
  104. method2.invoke(mWifManager, config, false);
  105. //mText.setText("wifi热点关闭");
  106. } catch (NoSuchMethodException e) {
  107. e.printStackTrace();
  108. } catch (IllegalArgumentException e) {
  109. e.printStackTrace();
  110. } catch (IllegalAccessException e) {
  111. e.printStackTrace();
  112. } catch (InvocationTargetException e) {
  113. e.printStackTrace();
  114. }
  115.  
  116. }
  117. }

end

Android 开发 创建WiFi、WiFi热点 ---开发集合的更多相关文章

  1. NX二次开发-创建NX9 NXOpenCPP Wizard开发向导模板

    这篇文章,我在CSDN,在唐工论坛都发过.http://www.nxopen.cn/forum.php?mod=viewthread&tid=2039&highlight=NX9 博客 ...

  2. [资料分享]迅为iTOP4412开发板-SDIO WiFi移植文档

    本文转自迅为:http://www.topeetboard.com 概述 近期需要把WiFi无线网络功能移植到iTOP-4412 开发平台,查阅了相关资料,经过一段时间的研究.调试,终于成功的将WiF ...

  3. Ubuntu14.04创建无线WiFi,android可以连接上网

    前提条件: ubuntu14.04 unity,已经通过有线连接到internet 一般环境下创建的wifi热点android设备是无法识别的,网上说通过ap-hotspot方式创建出来的热点手机可以 ...

  4. 7 无线wifi传输视频开发

    转载,侵删 7 无线wifi传输视频开发 MT7601的驱动源码提供了两种:AP模式和STA模式源码.此时我使用USB作为AP热点,电脑作为STA模式,并使用ORTP实现无线传输视频 7.1.AP模式 ...

  5. android 开发自建wifi热点的默认ip

    android 开发自建wifi热点的默认ip是:192.168.43.1  (小米3测试)

  6. 电脑创建WIFI/无线热点之后, 手机QQ能上浏览器不能上网

    这个完全是个人经验,绝对原创,请尊重博主原创权,转载请注明转于此博客. 问题如题,大家电脑创建无线热点之后, 有的人手机会出现QQ,微信能上网, 但是浏览器或者基于浏览器的那些比如应用商店不能上网, ...

  7. 创建假的wifi热点

    本帖介绍怎么创建假的wifi热点,然后抓取连接到这个wifi用户的敏感数据.我们还会给周围的无线路由器发送未认证的包,使这些路由器瘫痪,强迫用户连接(或自动连接)我们创建的假wifi热点. 这种攻击也 ...

  8. Android 网络开发之WIFI

    WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...

  9. Android深度探索--HAL与驱动开发----第五章读书笔记

    第五章主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器它是基于ARMI1内核,广泛应用于移动电话和通用处理等领域. 开发板从技术上说与我们 ...

随机推荐

  1. day71 菜单的排序 点击被选中

    菜单的排序:(给菜单设置权重,权重高的让他显示在上面) from django import template from django.conf import settings from collec ...

  2. 二十三. Python基础(23)--经典类和新式类

    二十三. Python基础(23)--经典类和新式类 ●知识框架   ●接口类&抽象类的实现 # 接口类&抽象类的实现 #①抛出异常法 class Parent(object):    ...

  3. 长字符串换行word-break

    word-break: break-all,每个字符换行 word-break: break-word按照单词换行,长字符之间换行

  4. SIMTRACE环境搭建

    搭建simtrace环境 工具环境搭建 仅作参考,具有时效性,请以官方文档为准. 跨平台编译工具arm-elf 参考链接:https://osmocom.org/projects/baseband/w ...

  5. 虚拟机U盘挂载

    虚拟机中U盘挂载 一.连接U盘 虚拟机中    虚拟机→可移动设备→Syntek USB......(U盘的名称)→连接: 二.查看U盘的UUID “lsblk -f”: UUID为   35E6-9 ...

  6. acrgis导出成tiff图片,全是黑色

    任务:将北京道路矢量数据转成栅格然后导出成tiff格式图片. 1. 北京道路有很多种,矢量合并---用到了merge工具 arcgis位置:data management----general---- ...

  7. 公共表达式消除(UVa 12219)

    紫书354页的题,将表达式树进行公共表达式消除,化为等价的图.因为需要判断某一个是否出现过,所以需要快速比较,采用哈希表的形式,将a~b与1~27一一对应,不采用0,因为0与0000是相同的,对于每一 ...

  8. 【SpringBoot】整合定时任务和异步任务

    ========================10.SpringBoot整合定时任务和异步任务处理 =============================== 1.SpringBoot定时任务s ...

  9. Mongo数据库基本操作

    从这两个类的继承来看,connection是继承了MongoClient的,建议使用MongoClient而不是使用Connection.(也就是说,MongoClient可以使用方法Connecti ...

  10. 串口发送端verilog代码分析

    串口发送端verilog代码分析 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////// ...