Android开发--WIFI实现

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

wifi的基本结构

在Android的官方文档中定义了如下五种状态:

WIFI_STATE_DISABLING  WIFI网卡正在关闭  0

WIFI_STATE_DISABLED   WIFI网卡不可用  1
WIFI_STATE_ENABLING    WIFI网卡正在打开  2
WIFI_STATE_ENABLED     WIFI网卡可用  3
WIFI_STATE_UNKNOWN    WIFI网卡状态不可知 4

要操作WIFI设备,就需要使用Context.getSystemService(Context.WIFI_SERVICE)来获取WifiManager对象,并通过这个对象来管理我们的WIFI设备。
如果要想得到周围的WIFI热点列表,可以使用WifiManager.getScanResults()返回一个ScanResult列表

这里列了很多,但是大致可以分为四个主要的类:ScanResult、wifiConfiguration、WifiInfo WifiManager

(1)ScanResult

主要是通过wifi 硬件的扫描来获取一些周边的wifi 热点的信息。 在我们进行wifi 搜索的时候,一般会搜到这些信息,首先是接入点名字、接入点信息的强弱、还有接入点使用的安全模式,是WPA、WPE;打开这个类,我们可以看到以下几个信息 BSSID 接入点的地址,这里主要是指小范围几个无线设备相连接所获取的地址,比如说两台笔记本通过无线网卡进行连接,双方的无线网卡分配的地址。
SSID 网络的名字,当我们搜索一个网络时,就是靠这个来区分每个不同的网络接入点。
Capabilities 网络接入的性能,这里主要是来判断网络的加密方式等。
Frequency 频率,每一个频道交互的MHz 数。
Level 等级,主要来判断网络连接的优先数。
这里只提供了一个方法,就是将获得信息编程字符串toString()。

(2)wifiConfiguration

在我们连通一个wifi 接入点的时候,需要获取到的一些信息。大家可以跟我们有线的设备进行对比一下。
这里的数据相对来说比较复杂一下。
六个子类
WifiConfiguration.AuthAlgorthm 用来判断加密方法。
WifiConfiguration.GroupCipher 获取使用GroupCipher 的方法来进行加密。
WifiConfiguration.KeyMgmt 获取使用KeyMgmt 进行。
WifiConfiguration.PairwiseCipher 获取使用WPA 方式的加密。
WifiConfiguration.Protocol 获取使用哪一种协议进行加密。
wifiConfiguration.Status 获取当前网络的状态。
对于上述加密感兴趣的朋友,可以在网上搜索相关的内容。
设置WifiConfiguration的属性:
WifiConfiguration.AuthAlgorthm 设置加密方法。
可选参数:LEAP只用于leap,
OPEN 被wpa/wpa2需要,
SHARED需要一个静态的wep key
WifiConfiguration.GroupCipher 使用GroupCipher 的方法来进行加密。
可选参数:CCMP,TKIP,WEP104,WEP40
WifiConfiguration.KeyMgmt 键管理机制(keymanagerment),使用KeyMgmt 进行。
可选参数IEEE8021X,NONE,WPA_EAP,WPA_PSK
WifiConfiguration.PairwiseCipher 设置加密方式。
可选参数 CCMP,NONE,TKIP
WifiConfiguration.Protocol 设置一种协议进行加密。
可选参数 RSN,WPA,
wifiConfiguration.Status 设置当前网络的状态。
可选参数CURRENT,DISABLED,ENABLED

(3)WifiInfo

在我们的wifi 已经连通了以后,可以通过这个类获得一些已经连通的wifi 连接的信息获取当前链接的信息,
这里信息就比较简单了,这里简单介绍一下这里的方法:
getBSSID() 获取BSSID
getDetailedStateOf() 获取客户端的连通性
getHiddenSSID() 获得SSID 是否被隐藏
getIpAddress() 获取IP 地址
getLinkSpeed() 获得连接的速度
getMacAddress() 获得Mac 地址
getRssi() 获得802.11n 网络的信号
getSSID() 获得SSID
getSupplicanState() 返回具体客户端状态的信息

(4)wifiManager

这个不用说,就是用来管理我们的wifi 连接,这里已经定义好了一些类,可以供我们使用。
这里来说相对复杂,里面的内容比较多,但是通过字面意思,我们还是可以获得很多相关的信息。这个类里面预先定义了许多常量,我们可以直接使用,不用再次创建。
这里还是简单介绍一下这里的方法:
addNetwork(WifiConfiguration config) 通过获取到的网络的链接状态信息,来添加网络
calculateSignalLevel(int rssi , int numLevels) 计算信号的等级
compareSignalLevel(int rssiA, int rssiB) 对比连接A 和连接B
createWifiLock(int lockType, String tag) 创建一个wifi 锁,锁定当前的wifi 连接
disableNetwork(int netId) 让一个网络连接失效
disconnect() 断开连接
enableNetwork(int netId, Boolean disableOthers) 连接一个连接
getConfiguredNetworks() 获取网络连接的状态
getConnectionInfo() 获取当前连接的信息
getDhcpInfo() 获取DHCP 的信息
getScanResulats() 获取扫描测试的结果
getWifiState() 获取一个wifi 接入点是否有效
isWifiEnabled() 判断一个wifi 连接是否有效
pingSupplicant() ping 一个连接,判断是否能连通
ressociate() 即便连接没有准备好,也要连通
reconnect() 如果连接准备好了,连通
removeNetwork() 移除某一个网络
saveConfiguration() 保留一个配置信息
setWifiEnabled() 让一个连接有效
startScan() 开始扫描
updateNetwork(WifiConfiguration config) 更新一个网络连接的信息
此外wifiManaer 还提供了一个内部的子类,也就是wifiManagerLock,WifiManagerLock 的作用是这样的,
在普通的状态下,如果我们的wifi 的状态处于闲置,那么网络的连通,将会暂时中断。
但是如果我们把当前的网络状态锁上,那么wifi 连通将会保持在一定状态,当然接触锁定之后,就会恢复常态


实现目标:搜索WIFI,手动输入密码并保存,连接WIFI。第二次连接该WIFI信号不需要输入密码

首先在AndroidManifest.XML中开启响应的权限

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission><!-- 允许程序改变网络链接状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission><!--允许程序访问访问WIFI网络状态信息  -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission><!-- 允许程序改变WIFI链接状态 -->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>	


1、开启WIFI

//开启WIFI
public void WifiOpen(){
	if(!localWifiManager.isWifiEnabled()){
		localWifiManager.setWifiEnabled(true);
	}
}


2、扫描WIFI信号

//扫描wifi
public void WifiStartScan(){
	localWifiManager.startScan();
}

3、得到扫描WIFI结果

//得到Scan结果
public List<ScanResult> getScanResults(){
	return localWifiManager.getScanResults();//得到扫描结果
}


4、得到WIFi的配置好的信息,包含配置好的密码

//得到Wifi配置好的信息
public void getConfiguration(){
	wifiConfigList = localWifiManager.getConfiguredNetworks();//得到配置好的网络信息
	for(int i =0;i<wifiConfigList.size();i++){
		Log.i("getConfiguration",wifiConfigList.get(i).SSID);
		Log.i("getConfiguration",String.valueOf(wifiConfigList.get(i).networkId));
	}
}


5、根据WIFI的名称SSID判定指定WIFI是否已经配置好,配置好则返回其networkId,用于连接。之前尝试了BSSID地址没成功,所以只能使用SSID

//判定指定WIFI是否已经配置好,依据WIFI的地址BSSID,返回NetId
public int IsConfiguration(String SSID){
	Log.i("IsConfiguration",String.valueOf(wifiConfigList.size()));
	for(int i = 0; i < wifiConfigList.size(); i++){
		Log.i(wifiConfigList.get(i).SSID,String.valueOf( wifiConfigList.get(i).networkId));
		if(wifiConfigList.get(i).SSID.equals(SSID)){//地址相同
    		return wifiConfigList.get(i).networkId;
		}
	}
	return -1;
}



6、如果需要连接的WIFI没有配置好,即没有保存密码。则为指定名称ssid的WIFI添加密码信息psw,添加成功后返回给其分配的networId,同于连接

//添加指定WIFI的配置信息,原列表不存在此SSID
public int AddWifiConfig(List<ScanResult> wifiList,String ssid,String pwd){
	int wifiId = -1;
	for(int i = 0;i < wifiList.size(); i++){
		ScanResult wifi = wifiList.get(i);
		if(wifi.SSID.equals(ssid)){
			Log.i("AddWifiConfig","equals");
			WifiConfiguration wifiCong = new WifiConfiguration();
			wifiCong.SSID = "\""+wifi.SSID+"\"";//\"转义字符,代表"
			wifiCong.preSharedKey = "\""+pwd+"\"";//WPA-PSK密码
			wifiCong.hiddenSSID = false;
			wifiCong.status = WifiConfiguration.Status.ENABLED;
			wifiId = localWifiManager.addNetwork(wifiCong);//将配置好的特定WIFI密码信息添加,添加完成后默认是不激活状态,成功返回ID,否则为-1
			if(wifiId != -1){
				return wifiId;
			}
		}
	}
	return wifiId;
}

7、根据步骤6配置好需要连接的WIFI密码信息后,下面通过networkId连接指定WIFI。在连接经过步骤6刚添加配置信息的WIFI信号之前需要重新执行下步骤4,得到新的配置好信息的列表

//连接指定Id的WIFI
public boolean ConnectWifi(int wifiId){
	for(int i = 0; i < wifiConfigList.size(); i++){
		WifiConfiguration wifi = wifiConfigList.get(i);
		if(wifi.networkId == wifiId){
			while(!(localWifiManager.enableNetwork(wifiId, true))){//激活该Id,建立连接
			    //status:0--已经连接,1--不可连接,2--可以连接
				Log.i("ConnectWifi",String.valueOf(wifiConfigList.get(wifiId).status));
			}
			return true;
		}
	}
	return false;
}


这只是简单的应用。

project源码:http://download.csdn.net/detail/liuhui_8989/7154671

相关文章
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
43 1
|
2月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
2天前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
65 19
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
1月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
70 14
|
1月前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
1月前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
39 5
|
1月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
139 3