Android 开发 创建WiFi、WiFi热点 ---开发集合
前言
此篇博客讲解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热点 ---开发集合的更多相关文章
- NX二次开发-创建NX9 NXOpenCPP Wizard开发向导模板
这篇文章,我在CSDN,在唐工论坛都发过.http://www.nxopen.cn/forum.php?mod=viewthread&tid=2039&highlight=NX9 博客 ...
- [资料分享]迅为iTOP4412开发板-SDIO WiFi移植文档
本文转自迅为:http://www.topeetboard.com 概述 近期需要把WiFi无线网络功能移植到iTOP-4412 开发平台,查阅了相关资料,经过一段时间的研究.调试,终于成功的将WiF ...
- Ubuntu14.04创建无线WiFi,android可以连接上网
前提条件: ubuntu14.04 unity,已经通过有线连接到internet 一般环境下创建的wifi热点android设备是无法识别的,网上说通过ap-hotspot方式创建出来的热点手机可以 ...
- 7 无线wifi传输视频开发
转载,侵删 7 无线wifi传输视频开发 MT7601的驱动源码提供了两种:AP模式和STA模式源码.此时我使用USB作为AP热点,电脑作为STA模式,并使用ORTP实现无线传输视频 7.1.AP模式 ...
- android 开发自建wifi热点的默认ip
android 开发自建wifi热点的默认ip是:192.168.43.1 (小米3测试)
- 电脑创建WIFI/无线热点之后, 手机QQ能上浏览器不能上网
这个完全是个人经验,绝对原创,请尊重博主原创权,转载请注明转于此博客. 问题如题,大家电脑创建无线热点之后, 有的人手机会出现QQ,微信能上网, 但是浏览器或者基于浏览器的那些比如应用商店不能上网, ...
- 创建假的wifi热点
本帖介绍怎么创建假的wifi热点,然后抓取连接到这个wifi用户的敏感数据.我们还会给周围的无线路由器发送未认证的包,使这些路由器瘫痪,强迫用户连接(或自动连接)我们创建的假wifi热点. 这种攻击也 ...
- Android 网络开发之WIFI
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...
- Android深度探索--HAL与驱动开发----第五章读书笔记
第五章主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器它是基于ARMI1内核,广泛应用于移动电话和通用处理等领域. 开发板从技术上说与我们 ...
随机推荐
- day71 菜单的排序 点击被选中
菜单的排序:(给菜单设置权重,权重高的让他显示在上面) from django import template from django.conf import settings from collec ...
- 二十三. Python基础(23)--经典类和新式类
二十三. Python基础(23)--经典类和新式类 ●知识框架 ●接口类&抽象类的实现 # 接口类&抽象类的实现 #①抛出异常法 class Parent(object): ...
- 长字符串换行word-break
word-break: break-all,每个字符换行 word-break: break-word按照单词换行,长字符之间换行
- SIMTRACE环境搭建
搭建simtrace环境 工具环境搭建 仅作参考,具有时效性,请以官方文档为准. 跨平台编译工具arm-elf 参考链接:https://osmocom.org/projects/baseband/w ...
- 虚拟机U盘挂载
虚拟机中U盘挂载 一.连接U盘 虚拟机中 虚拟机→可移动设备→Syntek USB......(U盘的名称)→连接: 二.查看U盘的UUID “lsblk -f”: UUID为 35E6-9 ...
- acrgis导出成tiff图片,全是黑色
任务:将北京道路矢量数据转成栅格然后导出成tiff格式图片. 1. 北京道路有很多种,矢量合并---用到了merge工具 arcgis位置:data management----general---- ...
- 公共表达式消除(UVa 12219)
紫书354页的题,将表达式树进行公共表达式消除,化为等价的图.因为需要判断某一个是否出现过,所以需要快速比较,采用哈希表的形式,将a~b与1~27一一对应,不采用0,因为0与0000是相同的,对于每一 ...
- 【SpringBoot】整合定时任务和异步任务
========================10.SpringBoot整合定时任务和异步任务处理 =============================== 1.SpringBoot定时任务s ...
- Mongo数据库基本操作
从这两个类的继承来看,connection是继承了MongoClient的,建议使用MongoClient而不是使用Connection.(也就是说,MongoClient可以使用方法Connecti ...
- 串口发送端verilog代码分析
串口发送端verilog代码分析 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////// ...