Android WIFI
参考链接
概念
相关权限
权限 |
说明 |
动态申请 |
android.permission.ACCESS_WIFI_STATE |
获取wifi状态 |
否 |
android.permission.CHANGE_WIFI_STATE |
更改wifi状态 |
否 |
android.permission.ACCESS_FINE_LOCATION |
精确定位(用于8.0以上扫描wifi) |
是 |
相关类
类名 |
说明 |
WifiManager |
Wifi统一管理类,执行wifi相关操作 WifiInfo:描述当前wifi信息 |
WifiInfo |
描述当前wifi信息 |
WifiConfiguration |
wifi网络配置信息 |
ScanResult |
获取附近wifi时返回的wifi热点信息 |
相关术语
名称 |
功能 |
SSID / ESSID |
描述热点的名称 |
BSSID |
热点的MAC地址 |
networkID |
数字型id |
RSSI / level |
wifi信号强弱等级 |
wifi的广播
IntentFilter filter = new IntentFilter();
if (Build.VERSION.SDK_INT >= 28) {
filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
}
// Android 8.0之后对静态注册的广播增加限制,保护用户隐私,故推荐使用动态注册
// WifiStateBroadcast 继承自 BroadcastReceiver
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
registerReceiver(new WifiStateBroadcast(), filter);</pre>
类型 |
说明 |
WifiManager.WIFI_STATE_CHANGED_ACTION |
wifi开关变化通知 |
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION |
wifi扫描结果通知 |
WifiManager.SUPPLICANT_STATE_CHANGED_ACTION |
wifi连接结果通知 |
WifiManager.NETWORK_STATE_CHANGED_ACTION |
网络状态变化通知 |
public class WifiStateBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action){
case WifiManager.WIFI_STATE_CHANGED_ACTION:
Log.d("打印", "onReceive: wifi开关变化通知");
break;
case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
Log.d("打印", "onReceive: 扫描wifi结果通知");
break;
case WifiManager.SUPPLICANT_STATE_CHANGED_ACTION:
Log.d("打印", "onReceive: wifi连接结果通知");
break;
case WifiManager.NETWORK_STATE_CHANGED_ACTION:
Log.d("打印", "onReceive: 网络状态变化");
break;
case LocationManager.PROVIDERS_CHANGED_ACTION:
Log.d("打印", "onReceive: 定位变化通知");
break;
}
}
}
Wifi的操作
开启或关闭wifi
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 开启或关闭wifi 对于Android 10.0及以上已经禁用
boolean isOpen = wifiManager.setWifiEnabled(true);
// 获取 Wifi 开关的状态
boolean isEnable = wifiManager.isWifiEnabled();
获取wifi状态
状态 |
值 |
说明 |
WIFI_STATE_DISABLING |
0 |
wifi关闭中,如果完成,那么会切换到 WIFI_STATE_DISABLED |
WIFI_STATE_DISABLED |
1 |
wifi已关闭 |
WIFI_STATE_ENABLING |
2 |
wifi开启中,如果完成,那么会切换到 WIFI_STATE_ENABLED |
WIFI_STATE_ENABLED |
3 |
wifi已开启 |
WIFI_STATE_UNKNOWN |
4 |
未知状态 |
// 获取wifi状态
int wifiState = wifiManager.getWifiState();
获取当前wifi信息
WifiInfo connectionInfo = wifiManager.getConnectionInfo();
String ssid = connectionInfo.getSSID();// 获取ssid
int ipAddress = connectionInfo.getIpAddress(); // ip的整数形式,需要转换成String形式
String bssid = connectionInfo.getBSSID(); // bssid
int rssi = connectionInfo.getRssi(); // rssi
int networkId = connectionInfo.getNetworkId(); // networkId
将 IP 转String形式
private static String formatIp(int ip){
String ipAddr = (ip & 0xFF) + "." +
((ip >> 8) & 0xFF) + "." +
((ip >> 16) & 0xFF) + "." +
(ip >> 24 & 0xFF);
return ipAddr;
}
扫描附近wifi
Google: startScan() This method was deprecated in API level P. The ability for apps to trigger scan requests will be removed in a future release.
翻译:
startScan() 在API级别P中已弃用此方法。在将来的版本中,将删除应用程序触发扫描请求的功能。
目前 Android 10 版本手机需要动态申请 ACCESS_COARSE_LOCATION 权限才能获取扫描结果
前台应用两分钟只能扫描4次,4次之后会返回最后一次扫描的结果
后台应用三十分钟(未试验)只能扫描1次,1次之后会返回最后一次扫描的结果
// 动态申请权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
boolean isScanSuccess = wifiManager.startScan(); // 开始扫描,成功返回true
// 结果会异步返回到注册的广播中
public class WifiStateBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)){
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<ScanResult> scanResults = wifiManager.getScanResults();
for (int i = 0; i < scanResults.size(); i++) {
ScanResult scanResult = scanResults.get(i);
String ssid = scanResult.SSID; // SSID
int level = scanResult.level; // 信号强弱
String bssid = scanResult.BSSID; // BSSID
String capabilities = scanResult.capabilities; // 加密方式:WPA/WPA2,WPA,WPA2,WEP,空(不加密)
}
}
}
}
连接wifi
/**
* ssid: 要连接的ssid
* password: 要连接的密码
* encryptType: 加密方式
*/
public static void connectWifi (Context context, String ssid, String password, int encryptType) {
if (!getWifiEnabled()){
return;
}
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.allowedAuthAlgorithms.clear();
wc.allowedGroupCiphers.clear();
wc.allowedKeyManagement.clear();
wc.allowedPairwiseCiphers.clear();
wc.allowedProtocols.clear();
wc.SSID = "\"" + ssid + "\"";
WifiConfiguration configuration = getWifiConfig(context, ssid);
if (configuration != null) {
wm.removeNetwork(configuration.networkId);
}
switch (encryptType) {
case 4:
// 不加密
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case 3:
//wep 加密
wc.hiddenSSID = true;
wc.wepKeys[0] = "\"" + password +"\"";
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case 0:
// wpa/wap2加密
case 1:
// wpa2加密
case 2:
// wpa加密
wc.preSharedKey = "\"" + password + "\"";
wc.hiddenSSID = true;
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.status = WifiConfiguration.Status.ENABLED;
break;
default:
break;
}
// 如果 network = -1,那么这个wifi是已经连接过的
int network = wm.addNetwork(wc);
if (network == -1){
connectWifi(context,ssid);
}else {
wm.disconnect();
wm.enableNetwork(network, true);
}
}
public static void connectWifi (Context context, String ssid) {
WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"" + ssid + "\"";
WifiConfiguration configuration = getWifiConfig(context, ssid);
if (configuration != null) {
wm.disconnect();
wm.enableNetwork(configuration.networkId, true);
}
}
工具类
/**
* wifi操作工具类
* 来源: 网络
*/
public class WifiUtils {
/**
* 判断wifi是否打开
* 需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean getWifiEnabled() {
@SuppressLint("WifiManagerLeak")
WifiManager wifiManager = (WifiManager) App.getContext().getSystemService(Context.WIFI_SERVICE);
return wifiManager.isWifiEnabled();
}
public static String getWifiIp(Context context){
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
return (ipAddress & 0xFF) + "." +
((ipAddress >> 8) & 0xFF) + "." +
((ipAddress >> 16) & 0xFF) + "." +
(ipAddress >> 24 & 0xFF);
}
/**
* @des 清除wifi配置信息
* @param context
* @param ssid
*/
public static void clearWifiInfo(Context context, String ssid) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String newSSID = "\"" + ssid + "\"";
if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
newSSID = "\"" + ssid + "\"";
} else {
newSSID = ssid;
}
WifiConfiguration configuration = getWifiConfig(context, newSSID);
configuration.allowedAuthAlgorithms.clear();
configuration.allowedGroupCiphers.clear();
configuration.allowedKeyManagement.clear();
configuration.allowedPairwiseCiphers.clear();
configuration.allowedProtocols.clear();
if (configuration != null) {
wm.removeNetwork(configuration.networkId);
wm.saveConfiguration();
}
}
public static WifiConfiguration getWifiConfig (Context context, String ssid) {
if (TextUtils.isEmpty(ssid)){
return null;
}
String newSSID;
if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
newSSID = "\"" + ssid + "\"";
} else {
newSSID = ssid;
}
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configuredNetworks = wm.getConfiguredNetworks();
for (WifiConfiguration configuration : configuredNetworks) {
if (newSSID.equalsIgnoreCase(configuration.SSID)) {
return configuration;
}
}
return null;
}
/**
* Wifi加锁方式
* @param capabilities
* @return
*/
public static int getWifiLockType(String capabilities){
if (TextUtils.isEmpty(capabilities)) {
return -1;
}
int encryptType;
if (capabilities.contains("WPA") && capabilities.contains("WPA2")) {
encryptType = 0;
} else if (capabilities.contains("WPA2")) {
encryptType = 1;
} else if (capabilities.contains("WPA")) {
encryptType = 2;
} else if (capabilities.contains("WEP")) {
encryptType = 3;
} else {
encryptType = 4;
}
return encryptType;
}
/**
*
* 获取WIFI列表
* <p>需要权限{@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>}</p>
* <p>注意Android6.0上需要主动申请定位权限,并且打开定位开关</p>
*
* @param context 上下文
* @return wifi列表
*/
public static List<ScanResult> getWifiList(Context context) {
WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<ScanResult> scanResults = wm.getScanResults();
WifiInfo info = wm.getConnectionInfo();
List<ScanResult> nlist = new ArrayList<>();
for (int i = 0; i < scanResults.size(); i++) {
if (scanResults.get(i).SSID.isEmpty()){
continue;
}
if (info != null && info.getSSID() != null && scanResults.get(i).BSSID.equals(info.getBSSID())) {
// 当前已连接设备不显示在列表中
continue;
}
if (scanResults.get(i).SSID.contains("0460")){
continue;
}
// 该热点SSID是否已在列表中
int position = getItemPosition(nlist, scanResults.get(i));
if (position != -1) {
// 已在列表
// 相同SSID热点,取信号强的
if (nlist.get(position).level < scanResults.get(i).level) {
nlist.remove(position);
nlist.add(position, scanResults.get(i));
}
} else {
nlist.add(scanResults.get(i));
}
}
Collections.sort(nlist, new Comparator<ScanResult>() {
@Override
public int compare(ScanResult scanResult1, ScanResult scanResult2) {
return scanResult2.level - scanResult1.level;
}
});
return nlist;
}
/**
* 返回item在list中的坐标
*/
private static int getItemPosition(List<ScanResult>list, ScanResult item) {
for (int i = 0; i < list.size(); i++) {
if (item.SSID.equals(list.get(i).SSID)) {
return i;
}
}
return -1;
}
public static boolean disconnect(Context context){
WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
return wm.disconnect();
}
/**
* 获取当前链接的WiFi信息
*
* @param context 上下文
* @return 当前wifi数据
*/
public static WifiInfo getCurrentWifi (Context context) {
WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo();
}
public static String getWifiEncryptTypeStr (String capabilitie) {
if (TextUtils.isEmpty(capabilitie)) {
return null;
}
String encryptType;
if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
encryptType = "WPA/WPA2 PSK";
} else if (capabilitie.contains("WPA2")) {
encryptType = "WPA2 PSK";
} else if (capabilitie.contains("WPA")) {
encryptType = "WPA PSK";
} else if (capabilitie.contains("WEP")) {
encryptType = "WEP";
} else {
encryptType = "NONE";
}
return encryptType;
}
/**
* wifi加密方式有5种
* 0 - WPA/WPA2 PSK
* 1 - WPA2 PSK
* 2 - WPA PSK
* 3 - WEP
* 4 - NONE
* @param capabilitie
* @return
*/
public static int getWifiEncryptType (String capabilitie) {
if (TextUtils.isEmpty(capabilitie)){
return -1;
}
int encryptType;
if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
encryptType = 0;
} else if (capabilitie.contains("WPA2")) {
encryptType = 1;
} else if (capabilitie.contains("WPA")) {
encryptType = 2;
} else if (capabilitie.contains("WEP")) {
encryptType = 3;
} else {
encryptType = 4;
}
return encryptType;
}
/**
* @des 连接已经保存过配置的wifi
* @param context
* @param ssid
*/
public static void connectWifi (Context context, String ssid) {
if (!getWifiEnabled()) {
return;
}
WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"" + ssid + "\"";
WifiConfiguration configuration = getWifiConfig(context, ssid);
if (configuration != null) {
wm.disconnect();
wm.enableNetwork(configuration.networkId, true);
}
}
/**
* @des 连接没有配置过的wifi
* @param context
* @param ssid
* @param password
* @param encryptType
*/
public static void connectWifi (Context context, String ssid, String password, int encryptType) {
if (!getWifiEnabled()){
return;
}
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.allowedAuthAlgorithms.clear();
wc.allowedGroupCiphers.clear();
wc.allowedKeyManagement.clear();
wc.allowedPairwiseCiphers.clear();
wc.allowedProtocols.clear();
wc.SSID = "\"" + ssid + "\"";
WifiConfiguration configuration = getWifiConfig(context, ssid);
if (configuration != null) {
wm.removeNetwork(configuration.networkId);
}
switch (encryptType) {
case 4:
// 不加密
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case 3:
//wep 加密
wc.hiddenSSID = true;
wc.wepKeys[0] = "\"" + password +"\"";
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case 0:
// wpa/wap2加密
case 1:
// wpa2加密
case 2:
// wpa加密
wc.preSharedKey = "\"" + password + "\"";
wc.hiddenSSID = true;
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.status = WifiConfiguration.Status.ENABLED;
break;
default:
break;
}
int network = wm.addNetwork(wc);
if (network == -1){
connectWifi(context,ssid);
}else {
wm.disconnect();
wm.enableNetwork(network, true);
}
}
public static void disConnectWifi (Context context, int networkId) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wm.disableNetwork(networkId);
wm.disconnect();
}
}
网友评论