一、Wifi基础知识

1、开发中常用类和常量

类名    功能
WifiManager    wifi统一管理类,进行各种wifi操作
WifiInfo    描述当前连接的wifi热点信息
WifiConfiguration    wifi网络配置信息
ScanResult    描述扫描出的wifi热点的信息,每个wifi对应一个ScanResult

2、常用wifi名词解释:

名称    功能
SSID    描述wifi热点的名称,就是大家搜索到的直接名称,如ChinaNet
BSSID    姑且理解成热点的mac地址,但实际有所不同
networkID    数字型的id
RSSI    描述wifi信号强弱的值,官方叫做level
 手机输入wifi密码连上后,下一次可以不用输入密码甚至是自动连接,就是因为手机中其实已经存储了wifi的信息,每个wifi有对应的networkid

WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
// 打开wifi开关
mWifiManager.setWifiEnabled(true);
// 关闭wifi开关
mWifiManager.setWifiEnabled(false);
wifi打开和关闭的状态常量,都封装在WifiManager中:可以在任何时候通过mWifiManager.getWifiState()来获取当前wifi的状态:mWifiManager.setWifiEnabled(true);
if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLING) {// wifi正在关闭
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {// wifi已关闭
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {// wifi正在开启
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {// wifi已开启
} else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_UNKNOWN) {// 未知状态
}

打开和关闭wifi的总开关:
wifi状态的变化会发出下列的广播事件:
WifiManager.WIFI_STATE_CHANGED_ACTION                  wifi开关变化通知
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION         wifi扫描结果通知
WifiManager.SUPPLICANT_STATE_CHANGED_ACTION   wifi连接结果通知
WifiManager.NETWORK_STATE_CHANGED_ACTION       网络状态变化通知

2、Wifi的搜索和连接

(1)搜索周围wifi信号:

// 搜索wifi热点
private void searchWifi() {if (!wifiManager.isWifiEnabled()) {//开启wifiwifiManager.setWifiEnabled(true);}wifiManager.startScan();
}

(2)获取扫描到的wifi

调用上述方法以后就开始搜索wifi了,当搜到wifi以后系统会发广播出来,监听广播来获取搜索到的wifi:因为wifiManager.getScanResults()每次获取的都是左右的扫到的wifi,所以不能直接把数据加到列表上,要清除列表上的数据,然后把扫到的数据放上来,不然会造成数据重复

private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {final String action = intent.getAction();if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {// wifi已成功扫描到可用wifi(包含之前扫到的)List<ScanResult> scanResults = wifiManager.getScanResults();wifiListAdapter.clear();wifiListAdapter.addAll(scanResults);} };

(3)wifi连接

private static final int WIFICIPHER_NOPASS = 1;
private static final int WIFICIPHER_WEP = 2;
private static final int WIFICIPHER_WPA = 3;listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {wifiManager.disconnect();final ScanResult scanResult = wifiListAdapter.getItem(position);String capabilities = scanResult.capabilities;int type = WIFICIPHER_WPA;if (!TextUtils.isEmpty(capabilities)) {if (capabilities.contains("WPA") || capabilities.contains("wpa")) {type = WIFICIPHER_WPA;} else if (capabilities.contains("WEP") || capabilities.contains("wep")) {type = WIFICIPHER_WEP;} else {type = WIFICIPHER_NOPASS;}}config = isExsits(scanResult.SSID);if (config == null) {if (type != WIFICIPHER_NOPASS) {//需要密码final EditText editText = new EditText(MainActivity.this);final int finalType = type;new AlertDialog.Builder(MainActivity.this).setTitle("请输入Wifi密码").setIcon(android.R.drawable.ic_dialog_info).setView(editText).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Log.w("AAA", "editText.getText():" + editText.getText());config = createWifiInfo(scanResult.SSID, editText.getText().toString(), finalType);connect(config);}}).setNegativeButton("取消", null).show();return;} else {config = createWifiInfo(scanResult.SSID, "", type);connect(config);}} else {connect(config);}}});/*** 判断当前wifi是否有保存** @param SSID* @return*   当没有获取到所要连接WiFi的配置信息时,我们就需要用到前面获取到的加密方式判断是否需*   要输入密码。如果加密方式为WAP或WEP时,则弹出提示框提示用户输入WiFi密码。用户输入密*   码后再调用connect(WifiConfiguration config)方法*/private WifiConfiguration isExsits(String SSID) {List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();for (WifiConfiguration existingConfig : existingConfigs) {if (existingConfig.SSID.equals("\"" + SSID + "\"")) {return existingConfig;}}// 返回空表示没保存过return null;}private void connect(WifiConfiguration config) {text_state.setText("连接中...");// 获取的networkId 如果为-1表示失败int networkID = wifiManager.addNetwork(config);wifiManager.enableNetwork(networkID, true);}
(4)、注册广播,监听连接的状态if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {text_state.setText("连接已断开");} else if (info.getState().equals(NetworkInfo.State.CONNECTED)) {WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);final WifiInfo wifiInfo = wifiManager.getConnectionInfo();text_state.setText("已连接到网络:" + wifiInfo.getSSID());} else {NetworkInfo.DetailedState state = info.getDetailedState();if (state == state.CONNECTING) {text_state.setText("连接中...");} else if (state == state.AUTHENTICATING) {text_state.setText("正在验证身份信息...");} else if (state == state.OBTAINING_IPADDR) {text_state.setText("正在获取IP地址...");} else if (state == state.FAILED) {text_state.setText("连接失败");}}}

以上代码只是监听了部分详细状态,还有很多其他的一些状态:
SCANNING:正在扫描
CONNECTING:连接中
AUTHENTICATING:正在进行身份验证
OBTAINING_IPADDR:正在获取Ip地址
CONNECTED:已连接
SUSPENDED:已暂停
DISCONNECTING:正在断开连接
DISCONNECTED:已断开
FAILED:失败
BLOCKED:已阻止
VERIFYING_POOR_LINK:暂时关闭(网络状况不佳)
CAPTIVE_PORTAL_CHECK:判断是否需要浏览器二次登录
二、Wifi Direct Connection介绍

1、简介

蓝牙有Ble轻量连接,Wifi当然也一样,WiFi Direct Connection点对点传输不用连接网络和热点,可进行近距离通信,比蓝牙传输要远,速度更快。

Wifi Direct API主要包括以下几个部分:

(1)WifiP2pManager,该类允许用户发现、请求和连接其他支持Wifi Direct的设备

(2)监听Wifi Direct请求的广播接收器

(3)被Wifi Direct框架检测到的时间通知,例如终止连接、发现新的Wifi Direct设备等

2、Wifi Direct广播接收器, 基本都是异步的,通过发广播来通知界面

WIFI_P2P_STATE_CHANGED_ACTION     检测Wifi Direct Connection是否可用,并且将检测结果通过此广播通知界面
WIFI_P2P_PEERS_CHANGED_ACTION    搜索可用的Wifi列表完成,收到此广播可以通过mWifiP2pManager.requestPeers方法获取所有的可用的wifi列表
WIFI_P2P_CONNECTION_CHANGED_ACTION    表示Wi-Fi连接状态发生了改变  
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION     响应设备的wifi状态变化

 public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {private WifiP2pManager.Channel channel;private WifiP2pManager manager;private MainActivity activity;public WiFiDirectBroadcastReceiver(WifiP2pManager.Channel channel, WifiP2pManager manager) {super();this.channel = channel;this.manager = manager;}@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {// 确定Wi-Fi Direct模式是否可用int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {// 可用} else {// 不可用}} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {// 发现设备后会发此通知来获取数据if (manager != null) {// 获取扫到的设备列表也是异步,因此需要回调manager.requestPeers(channel, new WifiP2pManager.PeerListListener() {@Overridepublic void onPeersAvailable(WifiP2pDeviceList peers) {// 参数就是扫到的wifi设备列表Collection<WifiP2pDevice> deviceList = peers.getDeviceList();}});}} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {// 当用户点击扫描到的列表上某个设备去连接的时候,连接状态会发此广播来通知,连接成功以后就可以获取WifiP2pInfo获取连接设备的具体信息了if (manager != null) {NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);if (networkInfo.isConnected()) {// 请求连接设备的信息,拿到WifiP2pInfo后就可以跟别的设备通信了manager.requestConnectionInfo(channel, new WifiP2pManager.ConnectionInfoListener() {@Overridepublic void onConnectionInfoAvailable(WifiP2pInfo info) {}});} else {// ...}}} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {//连接设备信息改变// ...}}}

3、初始化

WifiP2pManager mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
WifiP2pManager.Channel mChannel = mManager.initialize(this, getMainLooper(), null);
WiFiDirectBroadcastReceiver mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel);

4、查找设备

mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {@Overridepublic void onSuccess() {...}@Overridepublic void onFailure(int reasonCode) {...}
});

Wifi扫到设备后会统一回调,这里只是提示用户已经查找成功,具体获取扫到的列表数据要去广播(WIFI_P2P_PEERS_CHANGED_ACTION)中通过mManager.requestPeers()获取

5、连接设备

WifiP2pDevice device;
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
mManager.connect(mChannel, config, new ActionListener() {@Overridepublic void onSuccess() {// 连接成功的通知}@Overridepublic void onFailure(int reason) {// 连接失败的通知}
});

第4步的时候已经获取到了所有wifi列表,是一个Collection<WifiP2pDevice>集合,上述方法就是连接点击的设备,上面代码中的device就是要连接的设备,连接状态会通过广播(WIFI_P2P_CONNECTION_CHANGED_ACTION)告诉用户,用户可以在收到这个广播的时候获取连接的设备信息,从而进行通信。

6、获取连接设备的信息

NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {manager.requestConnectionInfo(channel, new WifiP2pManager.ConnectionInfoListener() {@Overridepublic void onConnectionInfoAvailable(WifiP2pInfo info) {}});
}

7、通信

得到WifiP2pInfo以后,我们就可以获取到连接设备的地址,这样就可以通过Socket和它通信了,我们手机端一般是连接端,所以是客户端,其他wifi设备一般是被连接端,所以是服务端,获取到流以后就可以传文件/文本等数据了

if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {// 当用户点击扫描到的列表上某个设备去连接的时候,连接状态会发此广播来通知,连接成功以后就可以获取WifiP2pInfo获取连接设备的具体信息了NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);if (networkInfo.isConnected()) {mManager.requestConnectionInfo(channel, new WifiP2pManager.ConnectionInfoListener() {@Overridepublic void onConnectionInfoAvailable(WifiP2pInfo info) {try {Socket socket = new Socket();InetSocketAddress inetSocketAddress = new InetSocketAddress(info.groupOwnerAddress.getHostAddress(), 5330);socket.connect(inetSocketAddress);OutputStream outputStream = socket.getOutputStream();InputStream inputStream = socket.getInputStream();}catch (Exception e) {}}});}
}

WiFi基础学习心得相关推荐

  1. 计算机基础与应用(上)笔记总结,计算机基础学习心得体会范文(通用3篇)

    计算机基础学习心得体会范文(通用3篇) 当我们对人生或者事物有了新的思考时,好好地写一份心得体会,这样可以记录我们的思想活动.那么要如何写呢?以下是小编精心整理的计算机基础学习心得体会范文(通用3篇) ...

  2. python心得体会-终于懂得python基础学习心得

    为了提高模块加载的速度,每个模块都会在__pycache__文件夹中放置该模块的预编译模块,命名为module.version.pyc,version是模块的预编译版本编码,一般都包含Python的版 ...

  3. 初中学习计算机基础,初中生计算机基础学习心得

    导语:为了提高自身的计算机管理业务素质,促进信息技术教学工作的顺利开展,我于2017年3月份在中小学继续教育网上选学了<计算机应用基础>的课程学习.以下是小编为您收集整理提供到的范文,欢迎 ...

  4. 计算机桌面设计总结及体会,计算机基础学习心得

    计算机基础学习心得 相关内容: 计算机硬件是指计算机系统中由电子,机械和光电元件等组成的各种物理装置的总称.下面是第一范文网带来的计算机硬件实习心得体会,欢迎欣赏.计算机硬件实习心得体会一:一.实习目 ...

  5. 医用计算机基础学习心得,计算机基础学习心得.doc

    计算机基础学习心得 计算机基础学习心得一:计算机基础学习心得 当今社会,到处充满机会与挑战.知识是我们面对这一切的筹码,而计算机知识则更为重要.如何在本科函授这样一种形式下,学好计算机课程,这是摆在我 ...

  6. 计算机硬件技术心得,计算机硬件技术基础学习心得.doc

    计算机硬件技术基础学习心得 计算机硬件技术基础学习心得 大学计算机基础学习心得 大学计算机基础学习心得 计算机,即电脑,随着科学技术的发展,不断进行着更新发展.伴随着计算机走入人类生活,它已成为人们日 ...

  7. WiFi基础学习到实战(三:WiFi网络“物理层”)

    欢迎大家一起学习探讨通信之WLAN.上节我们对802.11标准基于OSI模型,在"数据链路层"的定义进行了解,数据传送经过LLC层被封装为一个MSDU,通过MAC层封装为一个MPD ...

  8. WiFi基础学习到实战(一:802.11介绍)

    针对WLAN技术的前些课节分享,知识点比较独立,相互之间比较零散.以一个小功能或特性作为一次分享.通过一年多对WLAN技术的了解,为了彼此互相学习,在WLAN技术能有体系性的一起探讨进步.我们新起一个 ...

  9. WiFi基础学习到实战(二:WiFi网络“数据链路层”)

    欢迎大家一起学习探讨通信之WLAN.上节我们对802.11标准基于OSI模型进行了分析,主要将OSI模型的"数据链路层"定义分为"LLC层"和"MAC ...

最新文章

  1. flexbox布局_这是您可以使用FlexBox制作的5种布局
  2. 可以接受失败,但不选择放弃
  3. 蒙克:云计算安全问题被夸大
  4. Linux 的cp命令
  5. java 生成jar_java如何生成jar
  6. Python线程安全问题及解决方法
  7. 小米网卡驱动_小米是什么?(上)
  8. 2021年5月CCAA注册审核员考试认证通用基础真题
  9. 舱机器人尾巴毛茸茸_第一千五百二十四章 毛茸茸【二合一】
  10. bzoj2144 跳跳棋
  11. Comparable与Comparator的再学习与思考
  12. PowerBI强大的数据汇总能力:将几十张Excel二维表批量转换成一维表进行可视化分析
  13. 【转载】发一篇能激励大家拼搏的文章,文中内容属实
  14. Android应用数据备份
  15. 由“c++链接错误:未定义的引用“引发的思考
  16. 计算机网络——DNS域名解析服务器原理
  17. 2018金华高一计算机考试题目,2018年9月金华十校信息技术考试试题(含解析).docx...
  18. 北京林业大学计算机保研,北京林业大学2021年各专业保研数据详细分析
  19. Python数据转换-有符号短整型转换无符号短整型
  20. Android获取手机当前连接的WiFi信息(SSID,IP,连接状态)

热门文章

  1. Sharpness-Aware Minimization for Efficiently Improving Generalization
  2. Android上开发新浪微博OAuth2.0认证
  3. 服务器做raid 10后更换硬盘,做RAID10内置硬盘更换步骤
  4. qeephp数据库关联操作
  5. YMatrix 5.0 故障自动转移功能新实现,运维更方便!
  6. c盘扩展卷选项是灰的怎么办?win10系统c盘扩展卷灰色
  7. 什么是URI、URL和URN
  8. 全球新闻数据可视化(1)--数据下载与处理
  9. 【FL-GAN】Private FL-GAN: Differential Privacy Synthetic Data Generation Based on Federated Learning
  10. Windows 10安装Oracle时出现报错:INS-13001环境不满足最低要求