起源:因在售货机上需要设置WiFi,但是跳转之后发现无返回操作(其实Android系统在跳转系统子界面时有返回的操作,只不过被隐藏了,如果你的需求是跳转WiFi需要返回上级界面的话,可以点击此处来完美解决你的问题),故此想着自己获取WiFi列表然后填充到RecyclerView中,之后在进行WiFi连接,最终总结了此篇回忆 ~
虽然我写了Demo实现了一些需求,但是这方面的基础确实一般,索性总结的同时进行了二次理解,在学基础的时候借鉴了一篇老的文章,虽然现在可能有些方法已经被更新,但是十之八九皆是相同 ~
6.0版本中如果未开启GPS是无法获取到扫描列表
需要动态申请ACCESS_COARSE_LOCATION权限
Android官方文档中WiFi的五种状态
加密方式 | 场景 | 配置 |
---|---|---|
None | 开放网络,不加密 | 无需密码 |
WEP | 旧的加密方式,不推荐使用 | 仅需密码 |
WPA/WPA2 | 最常见的加密方式 | 仅需密码 |
EAP | 企业加密方式 | ID+密码验证 |
想要获得wifi的信息,就须要一个WifiManager对象
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
通过wifi 硬件的扫描来获取一些周边的wifi 热点的信息,包含接入点名字、接入点信息的强弱、还有接入点使用的安全模式,是WPA、WEP,内部只提供了一个方法,就是将获得信息编程字符串toString();
字段 | 含义 |
---|---|
BSSID | 接入点的地址,这里主要是指小范围几个无线设备相连接所获取的地址,比如说两台笔记本通过无线网卡进行连接,双方的无线网卡分配的地址 |
SSID | 网络的名字,当我们搜索一个网络时,就是靠这个来区分每个不同的网络接入点 |
Capabilities | 网络接入的性能,这里主要是来判断网络的加密方式等 |
Frequency | 频率,每一个频道交互的MHz 数 |
Level | 等级,主要来判断网络连接的优先数。 |
管理WiFi连接,内部提供了一个内部的wifiManagerLock子类,主要作用在普通的状态下,假设我们的wifi 的状态处于闲置。那么网络的连通,将会临时中断;可是假设我们把当前的网络状态锁上,那么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) | 更新一个网络连接的信息 |
WiFi连接成功之后,可通过WifiInfo类获取一些WiFi的具体信息
方法 | 含义 |
---|---|
getBSSID() | 获取BSSID |
getDetailedStateOf() | 获取client的连通性 |
getHiddenSSID() | 获得SSID 是否被隐藏 |
getIpAddress() | 获取IP 地址 |
getLinkSpeed() | 获得连接的速度 |
getMacAddress() | 获得Mac 地址 |
getRssi() | 获得802.11n 网络的信号 |
getSSID() | 获得SSID |
getSupplicanState() 返回详细client状态的信息 |
连通一个wifi 接入点的时候,需要获取到的一些信息 ~
类名 | 含义 |
---|---|
WifiConfiguration.AuthAlgorthm | 用来判断加密方法 |
WifiConfiguration.GroupCipher | 获取使用GroupCipher 的方法来进行加密 |
WifiConfiguration.KeyMgmt | 获取使用KeyMgmt 进行 |
WifiConfiguration.PairwiseCipher | 获取使用WPA 方式的加密 |
WifiConfiguration.Protocol | 获取使用哪一种协议进行加密 |
wifiConfiguration.Status | 获取当前网络的状态 |
此下方法较老,未必全部可用,只是当作笔记
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
public void openWifi(){
if(!wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(true);
}
}
private void closeWifi() {
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
}
}
public void WifiStartScan(){
wifiManager.startScan();
}
public List<ScanResult> getScanResults(){
//得到扫描结果
return wifiManager.getScanResults();
}
//连接指定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;
}
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));
}
}
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;
}
未必可用
//添加指定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;
}
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<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_NETWORK_STATE" />
public static boolean isWifiEnabled(Context mContext) {
if (mContext == null) {
throw new NullPointerException("Global context is null");
}
WifiManager wifiMgr = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
if (wifiMgr.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
ConnectivityManager connManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return wifiInfo.isConnected();
} else {
return false;
}
}
/**
* 获取当前连接WIFI的SSID - wifi名称
*/
public String getWifi_SSID(Context mContext) {
if (mContext == null) {
throw new NullPointerException("Global context is null");
}
if (isWifiEnabled(mContext)) {
WifiManager wifi = (WifiManager) mContext.getApplicationContext().getSystemService(WIFI_SERVICE);
if (wifi != null) {
WifiInfo wInfo = wifi.getConnectionInfo();
if (wInfo != null) {
String s = wInfo.getSSID();
if (s.length() > 2 && s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"') {
return s.substring(1, s.length() - 1);
}
}
}
}
return "";
}
获取WifiManager后可获取WiFi的IpAddress值,但是需要转换才能成为最后的ip地址
public String intToIp(int i) {
return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + ((i >> 24) & 0xFF);
}
/**
* 获取WiFi连接的ip地址
*/
public String getWifiIp(Context mContext) {
if (mContext == null) {
throw new NullPointerException("Global context is null");
}
WifiManager wifiMgr = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
if (isWifiEnabled(mContext)) {
int ipAsInt = wifiMgr.getConnectionInfo().getIpAddress();
if (ipAsInt == 0) {
return null;
} else {
return intToIp(ipAsInt);
}
} else {
return null;
}
}
/**
*权限申请
* */
private void registerPermission() {
//PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION:是设置权限之后回调函数中用于区别不同权限回调的自定义常量值
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
100);
} else {
getWifiList();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
getWifiList();
}
}
/**
* 获取WiFi列表
* */
public List<ScanResult> getWifiList() {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
List<ScanResult> scanWifiList = wifiManager.getScanResults();
List<ScanResult> wifiList = new ArrayList<>();
if (scanWifiList != null && scanWifiList.size() > 0) {
HashMap<String, Integer> signalStrength = new HashMap<>();
for (int i = 0; i < scanWifiList.size(); i++) {
ScanResult scanResult = scanWifiList.get(i);
Log.e("wifi", "搜索的wifi-ssid:" + scanResult.SSID);
if (!scanResult.SSID.isEmpty()) {
String key = scanResult.SSID + " " + scanResult.capabilities;
if (!signalStrength.containsKey(key)) {
signalStrength.put(key, i);
wifiList.add(scanResult);
}
}
}
} else {
Log.e("wifi", "没有搜索到wifi");
}
return wifiList;
}
static final int SECURITY_NONE = 0;
static final int SECURITY_WEP = 1;
static final int SECURITY_PSK = 2;
static final int SECURITY_EAP = 3;
private int getType(ScanResult result) {
if (result == null) {
return SECURITY_NONE;
}
String capbility = result.capabilities;
if (capbility == null || capbility.isEmpty()) {
return SECURITY_NONE;
}
// 如果包含WAP-PSK的话,则为WAP加密方式
if (capbility.contains("WPA-PSK") || capbility.contains("WPA2-PSK")) {
return SECURITY_WPA;
} else if (capbility.contains("WPA2-EAP")) {
return SECURYTI_EAP;
} else if (capbility.contains("WEP")) {
return SECURITY_WEP;
} else if (capbility.contains("ESS")) {
// 如果是ESS则没有密码
return SECURITY_NONE;
}
return SECURITY_NONE;
}
public static String getBSSID() {
if (wifiManager == null) {
return null;
}
WifiInfo info = wifiManager.getConnectionInfo();
Log.e("wifidemo", "getBSSID" + info.getBSSID());
if (info == null) {
return null;
}
return info.getBSSID();
}
public static String getGateway() {
if (wifiManager == null) {
return "";
}
InetAddress inetAddress = NetWorkUtils.intToInetAddress(wifiManager.getDhcpInfo().gateway);
if (inetAddress == null) {
return "";
}
return inetAddress.getHostAddress();
}
public static String getIpAddress() {
if (wifiManager == null) {
return "";
}
InetAddress inetAddress = NetWorkUtils.intToInetAddress(wifiManager.getConnectionInfo().getIpAddress());
if (inetAddress == null) {
return "";
}
return inetAddress.getHostAddress();
}
public static String getMacAddress() {
if (wifiManager == null) {
return "";
}
return wifiManager.getConnectionInfo().getMacAddress();
}
public boolean isCurrentConnect(String ssID) {
ssID = "\"" + ssID + "\"";
WifiInfo info = getWifiInfo();
//当前的ssid为空,未连接wifi
if (TextUtils.isEmpty(info.getSSID())) {
return false;
} else {//已连接
String tempSSID = info.getSSID();
return tempSSID.equals(ssID);
}
}
public static int getSignalNumsLevel(int rssi, int numLevels) {
if (wifiManager == null) {
return -1;
}
return WifiManager.calculateSignalLevel(rssi, numLevels);
}
public void refreshLocalWifiListData() {
/*逻辑说明:
1. 从扫描结果中将已经连接的wifi添加到wifi列表中
2. 从所有WiFilist中将已经添加过的已经连接的WiFi移除
3. 将剩余的WiFi添加到WiFilist中
实现了已经连接的WiFi处于wifi列表的第一位*/
//得到扫描结果
mWifiList.clear();
List<ScanResult> tmpList = mWifiManager.getScanResults();
for (ScanResult tmp : tmpList) {
if (isGivenWifiConnect(tmp.SSID)) {
mWifiList.add(tmp);
}
}
//从wifi列表中删除已经连接的wifi
for (ScanResult tmp : mWifiList) {
tmpList.remove(tmp);
}
mWifiList.addAll(tmpList);
}
public WifiConfiguration creatWifiConfiguration(String ssid, String password) {
ScanResult currentWIFI = null;
WifiSecutityEnum type = WifiSecutityEnum.NOON;
for (ScanResult temp : getmWifiList()) {
if (temp.SSID.equals(ssid)) {
currentWIFI = temp;
}
}
if (currentWIFI != null) {
Log.i(TAG, "creatWifiConfiguration: " + currentWIFI.toString());
type = getWifiSecurityMode(currentWIFI.capabilities);
}
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + ssid + "\"";
//如果当前连接的wifi被保存了密码,清除wifi保存信息
WifiConfiguration tempConfig = isWifiSave(ssid);
if (tempConfig != null) {
mWifiManager.removeNetwork(tempConfig.networkId);
mWifiManager.saveConfiguration();
}
switch (type) {
case NOON:
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case WEP:
config.hiddenSSID = true;
config.wepKeys[0] = "\"" + password + "\"";
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
break;
case WPA_AND_WPA2:
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
// config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
break;
}
return config;
}
public WifiConfiguration isWifiSave(String SSID) {
if (mWifiConfigurations != null) {
for (WifiConfiguration existingConfig : mWifiConfigurations) {
if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
return existingConfig;
}
}
}
return null;
}
public void disConnectWifi(){
wifiManager.disconnect();
}
public void disConnectionWifi(int netId) {
wifiManager.disableNetwork(netId);
wifiManager.disconnect();
}
public void wifiLocalHost() {
new Thread(new Runnable() {
@Override
public void run() {
InetAddress address = null;
try {
address = InetAddress.getLocalHost();
System.out.println("计算机名" + address.getHostName());
System.out.println("IP地址" + address.getHostAddress());
byte[] bytes = address.getAddress();//获取字节数组形式的IP地址
System.out.println("字节数组形式的Ip" + Arrays.toString(bytes));
System.out.println(address);//直接输出InetAddress对象
//根据机器名获取InetAddress实例
InetAddress address3 = null;
address3 = InetAddress.getByName("192.168.249.1");
System.out.println("计算机名" + address3.getHostName());
System.out.println("IP地址" + address3.getHostAddress());
/* get www.baidu.com's ip */
InetAddress remAdd = null; //取得远程InetAddress对象
remAdd = InetAddress.getByName("www.baidu.com");
System.out.println("本机IP地址:" + address.getHostAddress()); //得到本地IP地址
System.out.println("百度IP地址:" + remAdd.getHostAddress()); //得到百度IP地址
System.out.println("本机是否可达:" + address.isReachable(10000)); //10000是超时时间,10s
//很多情况是,某一域名对应的主机IP是可能有多个的,我们也可以一一的取回来。如下:
// 百度可能有多个IP地址,解析回来,所以我们可以用一个数组装起来
InetAddress[] addrs = InetAddress.getAllByName("www.baidu.com");
if (addrs != null && addrs.length > 0) {
for (InetAddress addr : addrs) {
System.out.println("--->" + addr.getHostAddress());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}