前言

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

权限

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

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

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

初始化WiFi管理

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

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硬件支持)

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

判断WiFi是否开启

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

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

开启或者关闭WiFi

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

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

搜索WiFi与获取WiFi设备列表

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

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

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

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

结果:

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

ScanResult可以获取的信息

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

                    CharSequence area = scanResult.venueName;   //WiFi接入点的地点名称
int frequency = scanResult.frequency; //频率
long refreshTime = scanResult.timestamp; //此WiFi最新的刷新时间戳
int level = scanResult.level; //信号强度
String encryption = scanResult.capabilities;//加密方式 例如:WEP/WAP/WAP2
String address = scanResult.BSSID; //WiFi的地址
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没有什么办法

public void scan(){
List<ScanResult> list = mWifiManager.getScanResults(); //获取WiFi列表
Log.e(TAG, "list 长度="+list.size());
for (ScanResult scanResult : list){
if (scanResult.SSID.equals("My_5g")){ //找到我们需要的WiFi
connectionWifi(scanResult.SSID,"winteam0901", scanResult.capabilities); //连接它
} }
} /**
* 连接WiFi的方法
* @param ssid wifi名称
* @param password WiFi密码
* @param capabilities 加密方式
*/
public void connectionWifi(String ssid, String password, String capabilities) {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
ssid = "\"" + ssid + "\""; //WiFi的名称配置需要加引号
password = "\"" + password + "\""; //WiFi的密码配置需要加引号
wifiConfiguration.SSID = ssid;
if (capabilities.contains("WPA")) {
wifiConfiguration.preSharedKey = password; } else if (capabilities.contains("WEP")) {
wifiConfiguration.wepKeys[0] = password;
wifiConfiguration.wepTxKeyIndex = 0;
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); } else if (capabilities.contains("OPEN")) {
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); }
mWifiManager.addNetwork(wifiConfiguration);
List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration item : wifiConfigurationList) {
if (item.SSID == null) {
continue;
}
if (item.SSID.equals(ssid)) {
mWifiManager.disconnect(); //断开连接
mWifiManager.enableNetwork(item.networkId, true); //连接我们需要的WiFi
mWifiManager.reconnect(); //重新连接
}
}
}

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

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

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

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

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

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

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

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

更新指定WiFi(更换密码)

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

  /**
* 更新WiFi
*/
public void undateWifi(String ssid, String password) {
List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration item : wifiConfigurationList) {
if (item.SSID == null) {
continue;
}
if (item.SSID.equals("\"" + ssid + "\"")) {
item.preSharedKey = "\"" + password + "\"";
mWifiManager.disconnect();
int id = mWifiManager.updateNetwork(item);
if (id == -1) { //id如果等于 -1 就说明更新失败了
return;
}
mWifiManager.enableNetwork(id, true); //启用连接WiFi
mWifiManager.reconnect();
}
}
}

移除指定WiFi

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

  /**
* 移除这个app保存的WiFi
*
* @param ssid
*/
public void removeWifi(String ssid) {
mWifiManager.startScan();
List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration item : wifiConfigurationList) {
if (item.SSID.equals("\"" + ssid + "\"")) {
mWifiManager.disconnect();
mWifiManager.removeNetwork(item.networkId);
mWifiManager.reconnect(); }
}
}

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

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

  这里获取的ssid 是带引号的

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

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

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

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

/**
* 移除引号
*
* @param content
* @return
*/
public String removeQuotationMarks(String content) {
content = content.substring(1, content.length() - 1);
return content; } /**
* 添加引号
*
* @param content
* @return
*/
public String addQuotationMarks(String content) {
content = "\"" + content + "\"";
return content;
}

格式化wifi信号值

 /**
* WifiInfo.MIN_RSSI = -126;
* WifiInfo.MAX_RSSI = 200;
*
* Quality Excellent Good Fair Poor
* dBm -30 ~ -61 -63 ~ -73 -75 ~ -85 -87 ~ -97
*
* @param rssi
* @return
*/
public static int formatLevel(int rssi) {
if (rssi < -97){
return 0;
}else if (rssi < -87){
return 1;
}else if (rssi < -75){
return 2;
}else if (rssi < -63){
return 3;
}else {
return 4;
}
}

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

/**
* 将idAddress转化成string类型的Id字符串
*
* @param idString
* @return
*/
private static String getStringId(int idString) {
StringBuffer sb = new StringBuffer();
int b = (idString >> 0) & 0xff;
sb.append(b + ".");
b = (idString >> 8) & 0xff;
sb.append(b + ".");
b = (idString >> 16) & 0xff;
sb.append(b + ".");
b = (idString >> 24) & 0xff;
sb.append(b);
return sb.toString();
}

获取WiFi状态

注册广播

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

接收广播处理

class WiFiChangeReceiver extends BroadcastReceiver{

        @Override
public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
int switchState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);//得到WiFi开关状态值
switch (switchState) {
case WifiManager.WIFI_STATE_DISABLED://WiFi已关闭
WiFIStateData data1 = new WiFIStateData();
data1.time = mDf.format(System.currentTimeMillis());
data1.state = "WiFi关闭";
mDao.insert(data1);
EventBus.getDefault().post(msgData);
Log.e(TAG, "WiFi关闭");
break;
case WifiManager.WIFI_STATE_DISABLING://WiFi关闭中
Log.e(TAG, "WiFi关闭中");
break;
case WifiManager.WIFI_STATE_ENABLED://WiFi已开启
WiFIStateData data2 = new WiFIStateData();
data2.time = mDf.format(System.currentTimeMillis());
data2.state = "WiFi开启";
mDao.insert(data2);
EventBus.getDefault().post(msgData);
Log.e(TAG, "WiFi开启");
break;
case WifiManager.WIFI_STATE_ENABLING://WiFi开启中
Log.e(TAG, "WiFi开启中");
break;
case WifiManager.WIFI_STATE_UNKNOWN://WiFi状态未知
WiFIStateData data3 = new WiFIStateData();
data3.time = mDf.format(System.currentTimeMillis());
data3.state = "WiFi状态未知";
mDao.insert(data3);
EventBus.getDefault().post(msgData);
Log.e(TAG, "WiFi状态未知");
break;
default:
break;
}
} if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){ //网络状态改变行为
Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);//得到信息包
if (parcelableExtra != null){、蓝牙——
NetworkInfo networkInfo = (NetworkInfo)parcelableExtra;//得到网络信息
NetworkInfo.DetailedState detailedState = networkInfo.getDetailedState();
switch (detailedState){
case CONNECTED:
mDisconnectState = true;
WiFIStateData data4 = new WiFIStateData();
data4.time = mDf.format(System.currentTimeMillis());
data4.state = "已经连接";
mDao.insert(data4);
EventBus.getDefault().post(msgData);
Log.e(TAG, "已经连接");
break;
case DISCONNECTED:
if (mDisconnectState){
mDisconnectState = false;
WiFIStateData data5 = new WiFIStateData();
data5.time = mDf.format(System.currentTimeMillis());
data5.state = "已经断开";
mDao.insert(data5);
EventBus.getDefault().post(msgData);
Log.e(TAG, "已经断开");
}
break;
case IDLE: WiFIStateData data6 = new WiFIStateData();
data6.time = mDf.format(System.currentTimeMillis());
data6.state = "空闲中";
mDao.insert(data6);
EventBus.getDefault().post(msgData);
Log.e(TAG, "空闲中"); break;
case AUTHENTICATING: WiFIStateData data7 = new WiFIStateData();
data7.time = mDf.format(System.currentTimeMillis());
data7.state = "认证中";
mDao.insert(data7);
EventBus.getDefault().post(msgData);
Log.e(TAG, "认证中"); break;
case BLOCKED: WiFIStateData data8 = new WiFIStateData();
data8.time = mDf.format(System.currentTimeMillis());
data8.state = "认证失败";
mDao.insert(data8);
EventBus.getDefault().post(msgData);
Log.e(TAG, "认证失败"); break;
case CAPTIVE_PORTAL_CHECK: WiFIStateData data9 = new WiFIStateData();
data9.time = mDf.format(System.currentTimeMillis());
data9.state = "连接检查";
mDao.insert(data9);
EventBus.getDefault().post(msgData);
Log.e(TAG, "连接检查"); break;
default:
break;
}
} } }
}

WiFi设备信息的数据清洗

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

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

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

package com.zh.zwifidemo.wifi;

import java.util.List;

public class WifiDataBean {
private ConnectionWifi connectionWifi; //当前正在连接的WiFi
private List<ConfigWifi> configWifiList;//已经配置过的WiFi
private List<OtherWifi> otherWifiList; //搜索到的其他WiFi public ConnectionWifi getConnectionWifi() {
return connectionWifi;
} public void setConnectionWifi(ConnectionWifi connectionWifi) {
this.connectionWifi = connectionWifi;
} public List<ConfigWifi> getConfigWifiList() {
return configWifiList;
} public void setConfigWifiList(List<ConfigWifi> configWifiList) {
this.configWifiList = configWifiList;
} public List<OtherWifi> getOtherWifiList() {
return otherWifiList;
} public void setOtherWifiList(List<OtherWifi> otherWifiList) {
this.otherWifiList = otherWifiList;
} public class ConnectionWifi{
private String ssid;
private Integer level; //信号强度
private Integer ipAddress;
private Integer frequency;//频率 public String getSsid() {
return ssid;
} public void setSsid(String ssid) {
this.ssid = ssid;
} public Integer getLevel() {
return level;
} public void setLevel(Integer level) {
this.level = level;
} public Integer getIpAddress() {
return ipAddress;
} public void setIpAddress(Integer ipAddress) {
this.ipAddress = ipAddress;
} public Integer getFrequency() {
return frequency;
} public void setFrequency(Integer frequency) {
this.frequency = frequency;
}
} public class ConfigWifi{
private String ssid;
private Integer level; //信号强度
/*
public static final int CURRENT = 0; 已连接
public static final int DISABLED = 1; 停用,错误密码
public static final int ENABLED = 2; 已保存,未连接
*/
private Integer state;
private String capabilities; public String getSsid() {
return ssid;
} public void setSsid(String ssid) {
this.ssid = ssid;
} public Integer getLevel() {
return level;
} public void setLevel(Integer level) {
this.level = level;
} public Integer getState() {
return state;
} public void setState(Integer state) {
this.state = state;
} public String getCapabilities() {
return capabilities;
} public void setCapabilities(String capabilities) {
this.capabilities = capabilities;
}
} public class OtherWifi{
private String ssid;
private Integer level; //信号强度
private String capabilities;//安全形式 public String getSsid() {
return ssid;
} public void setSsid(String ssid) {
this.ssid = ssid;
} public Integer getLevel() {
return level;
} public void setLevel(Integer level) {
this.level = level;
} public String getCapabilities() {
return capabilities;
} public void setCapabilities(String capabilities) {
this.capabilities = capabilities;
}
} }

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

public WifiDataBean getWifiBean() {
WifiDataBean wifiDataBean = new WifiDataBean();
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
List<ScanResult> scanResultList = new ArrayList<>();
List<WifiConfiguration> configurationList = new ArrayList<>();
scanResultList.addAll(mWifiManager.getScanResults());
configurationList.addAll(mWifiManager.getConfiguredNetworks()); List<WifiDataBean.ConfigWifi> configWifiList = new ArrayList<>();
List<WifiDataBean.OtherWifi> otherWifiList = new ArrayList<>(); /*
处理当前正在连接中的WiFi
*/
if (wifiInfo.getIpAddress() == 0) {
wifiDataBean.setConnectionWifi(null);
} else {
WifiDataBean.ConnectionWifi connectionWifi = wifiDataBean.new ConnectionWifi();
connectionWifi.setSsid(wifiInfo.getSSID());
connectionWifi.setLevel(wifiInfo.getRssi());
connectionWifi.setIpAddress(wifiInfo.getIpAddress());
connectionWifi.setFrequency(wifiInfo.getFrequency());
wifiDataBean.setConnectionWifi(connectionWifi);
} /*
处理已经配置过的WiFi
*/
if (configurationList.isEmpty()) {
wifiDataBean.setConfigWifiList(configWifiList); } else {
for (int i = 0; i < configurationList.size(); i++) { //除去null的WiFi
WifiConfiguration configuration = configurationList.get(i);
if (configuration.SSID == null) {
configurationList.remove(configuration);
}
} if (wifiDataBean.getConnectionWifi() != null) {
for (int i = 0; i < configurationList.size(); i++) { //去除正在连接的WiFi item
WifiConfiguration configuration = configurationList.get(i);
if (configuration.SSID.equals(wifiDataBean.getConnectionWifi().getSsid())) {
configurationList.remove(configuration);
}
}
} for (int i = 0; i < configurationList.size(); i++) { //除去重复的WiFi
WifiConfiguration configuration = configurationList.get(i);
for (int j = i + 1; j < configWifiList.size(); j++) {
WifiConfiguration item = configurationList.get(j);
if (configuration.SSID.equals(item.SSID)) {
configurationList.remove(item);
} }
} for (int i = 0; i < configurationList.size(); i++) { //添加配置过的WiFi数据
WifiConfiguration configuration = configurationList.get(i);
WifiDataBean.ConfigWifi configWifi = wifiDataBean.new ConfigWifi();
configWifi.setSsid(configuration.SSID);
configWifi.setState(configuration.status);
for (int j = 0; j < scanResultList.size(); j++) {
ScanResult scanResult = scanResultList.get(j);
if (removeQuotationMarks(configuration.SSID).equals(scanResult.SSID)) {
configWifi.setLevel(scanResult.level);
}
}
if (configWifi.getLevel() == null) {
configWifi.setLevel(-98); }
if (configuration.preSharedKey != null && !configuration.preSharedKey.equals("")) {
configWifi.setCapabilities("WPA");
} else if (configuration.wepKeys[0] != null && !configuration.wepKeys[0].equals("")) {
configWifi.setCapabilities("WEP");
} else {
configWifi.setCapabilities("OPEN");
}
configWifiList.add(configWifi);
}
wifiDataBean.setConfigWifiList(configWifiList);
} /*
设置其他WiFi
*/
if (scanResultList.isEmpty()) {
wifiDataBean.setOtherWifiList(otherWifiList); } else {
for (int i = 0; i < scanResultList.size(); i++) { //去除null
ScanResult scanResult = scanResultList.get(i);
if (scanResult.SSID == null) {
scanResultList.remove(scanResult);
}
} if (wifiDataBean.getConnectionWifi() != null){
for (int i = 0; i < scanResultList.size(); i++) { //去除已连接的
ScanResult scanResult = scanResultList.get(i);
if (scanResult.SSID.equals(removeQuotationMarks(wifiDataBean.getConnectionWifi().getSsid()))) {
scanResultList.remove(scanResult);
}
}
} for (int i = 0; i < scanResultList.size(); i++) { //去除已配置的
ScanResult scanResult = scanResultList.get(i);
for (int j = 0; j < configWifiList.size(); j++) {
WifiDataBean.ConfigWifi configWifi = configWifiList.get(j);
if (removeQuotationMarks(configWifi.getSsid()).equals(scanResult.SSID)) {
scanResultList.remove(scanResult);
}
}
} for (int i = 0; i < scanResultList.size(); i++) { //去除重复的
ScanResult scanResult = scanResultList.get(i);
for (int j = i + 1; j < scanResultList.size(); j++) {
ScanResult item = scanResultList.get(j);
if (scanResult.SSID.equals(item.SSID)) {
scanResultList.remove(item);
}
}
} for (int i = 0; i < scanResultList.size(); i++) {
ScanResult scanResult = scanResultList.get(i);
WifiDataBean.OtherWifi otherWifi = wifiDataBean.new OtherWifi();
otherWifi.setSsid(scanResult.SSID);
otherWifi.setLevel(scanResult.level);
otherWifi.setCapabilities(scanResult.capabilities);
otherWifiList.add(otherWifi);
}
wifiDataBean.setOtherWifiList(otherWifiList);
}
return wifiDataBean;
}

WIFI热点

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

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

/*
content:创建WiFi热点class
time:2018-7-23 11:23
build:
*/ public class WiFiAP {
private static WiFiAP mWiFiAP;
private static WifiManager mWifManager;
private WiFiAP(){} public static WiFiAP getI(){
if (mWiFiAP == null){
mWiFiAP = new WiFiAP();
}
return mWiFiAP;
} /**
* 手动得到系统权限的方法,提供给外部启动系统权限界面,以实现手动添加系统权限
* @param context 外部activity的上下文
*/
public void setPermissions(Context context){
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent); } /**
* 打开热点并且创建WiFi热点的方法
* @param context 外部上下文
* @param ssid 要创建WiFi热点的账号名称
* @param password 要创建WiFi热点的密码
* 注意,此方法直接使用WPA2_PSK 的安全策略创建WiFi热点,低版本的Android系统如果需要使用请切换。
*/
@SuppressLint("MissingPermission")
public void openWiFiAP(Context context, String ssid, String password){ mWifManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); if (mWifManager.isWifiEnabled()) {
//如果wifi处于打开状态,则关闭wifi,
mWifManager.setWifiEnabled(false);
}
WifiConfiguration config = new WifiConfiguration();
config.SSID = ssid;
config.preSharedKey = password;
config.hiddenSSID = false;//是否隐藏热点true=隐藏
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);//开放系统认证
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
int indexOfWPA2_PSK = 4;
//从WifiConfiguration.KeyMgmt数组中查找WPA2_PSK的值
for (int i = 0; i < WifiConfiguration.KeyMgmt.strings.length; i++)
{
if(WifiConfiguration.KeyMgmt.strings[i].equals("WPA2_PSK"))
{
indexOfWPA2_PSK = i;
break;
}
}
//WifiConfiguration.KeyMgmt.WPA_PSK
config.allowedKeyManagement.set(indexOfWPA2_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
//通过反射调用设置热点
try {
Method method = mWifManager.getClass().getMethod(
"setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
boolean enable = (Boolean) method.invoke(mWifManager, config, true); if (enable) {
Log.e("WiFiAP", "热点已开启 SSID:" + ssid + " Password:"+password);
} else {
Log.e("WiFiAP", "创建热点失败");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("WiFiAP", "创建热点失败"+e);
} } /**
* 关闭WiFi热点的方法
* @param context 外部activity的上下文
*/
public void closeWiFiAP(Context context){
mWifManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if( mWifManager == null){
Log.e("closeWiFiAP", "Error: mWifManager is null");
return;
}
try {
Method method = mWifManager.getClass().getMethod("getWifiApConfiguration");
method.setAccessible(true);
WifiConfiguration config = (WifiConfiguration) method.invoke(mWifManager);
Method method2 = mWifManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method2.invoke(mWifManager, config, false);
//mText.setText("wifi热点关闭");
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} }
}

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. jq demo 点击选中元素左右移动

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  2. Windows环境安装tesseract-ocr 4.00并配置环境变量

    最近要做文字识别,不让直接用别人的接口,所以只能尝试去用开源的类库.tesseract-ocr是惠普公司开源的一个文字识别项目,通过它可以快速搭建图文识别系统,帮助我们开发出能识别图片的ocr系统.因 ...

  3. ServiceStack.Redis遇到的问题:ServiceStack.Redis.Generic.RedisTypedClient`1”的方法“get_Db”没有实现。

    问题: ServiceStack.Redis.Generic.RedisTypedClient`1”的方法“get_Db”没有实现. 解决方案: step 1::引用的三个 包版本保持一致 Servi ...

  4. 【未解决】对于使用Windows的IDEA进行编译的文件,但无法在Linux系统中统计代码行数的疑问

    在我学习使用Windows的IDEA的过程中,将代码文件转移到Linux虚拟机当中,但无法在Linux系统中统计代码行数. 注意:拷贝进虚拟机的文件均能编译运行. 具体过程如下: root@yogil ...

  5. @MapperScan使用

    @MapperScan:要扫描mapper类包的路径 还可以扫描多个包,如: @MapperScan({"com.kfit.demo","com.kfit.user&qu ...

  6. vm虚拟机下ubuntu连接上ssr

    第一步: 第二步: 第三步: 第四步: 完成!

  7. Vue2.0

    Vue 1.0到2.0的变化: 1.在每个组件的模板中,不再支持片段代码 组件中的模板: 之前: <template> <h3我是组件<strong>我是加粗模板< ...

  8. python 参数传递 传值还是传引用

    个人推测结论: 可变对象传引用,不可变对象传值 python里的变量不同于c中地址储值模型 a=100 b=100 print(id(a),id(b),a==b,a is b) #8790877986 ...

  9. CF1109D Sasha and Interesting Fact from Graph Theory

    CF1109D Sasha and Interesting Fact from Graph Theory 这个 \(D\) 题比赛切掉的人基本上是 \(C\) 题的 \(5,6\) 倍...果然数学计 ...

  10. if 循环

    age_of_princal = 56guess_age = int(input(">>:")) if guess_age == age_of_princal: pri ...