最近在做Android WIFI相关的东西,在这里记录一下,方便后面需要的时候查看。
首先感谢网上各位大神的分享,正是看了这些博客分享之后才能把这一块的功能做出来。
直接看代码:
先建议看一下谷歌的官方文档,里面写清楚了很多类,方法的用法。
(1)WIFI开发肯定需要使用WIFI模块,那首先就是要在Manifest文件中声明需要使用WIFI模块:
<!-- 需要使用wifi -->
<uses-feature android:name="android.hardware.wifi" />
(2)需要在Manifest文件中声明需要使用的相关权限,注意,这里除了WIFI的相关权限还需要使用定位权限,同时注意在Android6.0,也就是SDK >=23的时候需要进行动态权限申请,特别是定位权限,属于危险权限,没有声明和申请会导致程序崩溃:
<!-- 配置wifi权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--定位权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
(3)需要注册WIFI变化的相关广播,根据这些广播可以即时更新WIFI当前的状态,注意虽然WifiManager中的相关方法虽然提供了打开/关闭WIFI,扫描附近WIFI等方法,同时返回boolean值以提供操作是否成功,但是这些值并不能完全拿来做判断,毕竟打开/关闭,扫描这些都是耗时操作,还是要根据广播提供的数据做更加精确的判断
<!--wifi变化的广播监听-->
<receiver
android:name=".utils.wifi.WifiChangeBroadcast"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.wifi.SCAN_RESULTS" />
<action android:name="android.net.wifi.STATE_CHANGE" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<!--信号强度变化,暂时不做监听-->
<!--<action android:name="android.net.wifi.RSSI_CHANGED" />-->
<!--是否正在获得IP地址-->
<action android:name="android.net.wifi.supplicant.STATE_CHANGE" />
</intent-filter>
</receiver>
(4)定义一个接口,当WIFI状态发生改变的时候,通过这个接口来通知Activity执行不同的操作
public interface WifiLinkStateListener {
//wifi信号强度变化
void rssiChange();
//密码认证错误
void errorAuthKey();
//扫描完成
void finishScanWifi();
//开关状态
void openedWifi();//已经开启
void openingWifi();//正在开启
void closedWifi();//已经关闭
void closingWifi();//正在关闭
//连接状态
void disconnectedWifi();//断开连接
void connectingWifi();//正在连接
void connectedSuccess();//连接成功
void connectingIpAddress();//正在获取IP
void connectFailed();//连接失败
}
(5)定义一个全局的广播接收器:
private static WifiLinkStateListener wifiLinkStateListener;
private static final String WIFI_STATE_CHANGE = "android.net.wifi.WIFI_STATE_CHANGED";//wifi开关变化
private static final String WIFI_SCAN_RESULT = "android.net.wifi.SCAN_RESULTS";//扫描结果变化
private static final String WIFI_LINK_RESULT = "android.net.wifi.STATE_CHANGE";//连接结果通知
private static final String NETWORK_STATE_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";//网络变化
private static final String WIFI_GET_IDADDRESS = "android.net.wifi.supplicant.STATE_CHANGE";//是否正在获得IP地址
private static final String WIFI_POWER_CHANGE = "android.net.wifi.RSSI_CHANGED";//wifi强度变化
//设置接口
public void setWifiLinkStateListener(WifiLinkStateListener wifiLinkStateListener) {
this.wifiLinkStateListener = wifiLinkStateListener;
}
@Override
public void onReceive(Context context, Intent intent) {
String broadcastAction = intent.getAction();
LogUtils.logI("广播监听:" + broadcastAction);
if (wifiLinkStateListener != null) {
}
switch (broadcastAction) {
case WIFI_STATE_CHANGE:
//wifi开关发生改变
if (wifiLinkStateListener != null) {
getWifiEnableState(intent);
}
break;
case WIFI_SCAN_RESULT:
//扫描完成之后直接调用接口
if (wifiLinkStateListener != null) {
wifiLinkStateListener.finishScanWifi();
}
break;
case WIFI_LINK_RESULT:
//连接状态发生改变的时候,获取当前wifi的连接状态
if (wifiLinkStateListener != null) {
getWifiLinkState(intent);
}
break;
case NETWORK_STATE_CHANGE:
break;
case WIFI_GET_IDADDRESS:
//正在获取ip地址
//密码认证出错
int error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -100);
if (error == WifiManager.ERROR_AUTHENTICATING) {
//密码认证错误
LogUtils.logI("密码认证错误");
if (wifiLinkStateListener != null) {
wifiLinkStateListener.errorAuthKey();
}
}
break;
case WIFI_POWER_CHANGE:
//信号变化之后,调用接口
if (wifiLinkStateListener != null) {
wifiLinkStateListener.rssiChange();
}
break;
}
}
//wifi开关发生改变时,获取wifi状态
private void getWifiEnableState(Intent intent) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
switch (wifiState) {
case WifiManager.WIFI_STATE_ENABLED:
//已经开启
LogUtils.logI("WIFI已经开启");
wifiLinkStateListener.openedWifi();
break;
case WifiManager.WIFI_STATE_ENABLING:
//正在开启
LogUtils.logI("wifi正在开启");
wifiLinkStateListener.openingWifi();
break;
case WifiManager.WIFI_STATE_DISABLED:
//已经关闭
LogUtils.logI("wifi已经关闭");
wifiLinkStateListener.closedWifi();
break;
case WifiManager.WIFI_STATE_DISABLING:
//正在关闭
LogUtils.logI("wifi正在关闭");
wifiLinkStateListener.closingWifi();
break;
}
}
//当连接状态发生改变的时候,获取连接状态
private void getWifiLinkState(Intent intent) {
if (intent != null) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (info.getDetailedState().equals(NetworkInfo.DetailedState.DISCONNECTED)) {
//连接已经断开
LogUtils.logI("连接已经断开");
wifiLinkStateListener.disconnectedWifi();
} else if (info.getDetailedState().equals(NetworkInfo.DetailedState.CONNECTING)) {
//正在连接
LogUtils.logI("正在连接");
wifiLinkStateListener.connectingWifi();
} else if (info.getDetailedState().equals(NetworkInfo.DetailedState.CONNECTED)) {
//已经连接
LogUtils.logI("成功连接到网络");
wifiLinkStateListener.connectedSuccess();
} else if (info.getDetailedState().equals(NetworkInfo.DetailedState.OBTAINING_IPADDR)) {
LogUtils.logI("正在获取IP地址");
wifiLinkStateListener.connectingIpAddress();
} else if (info.getDetailedState().equals(NetworkInfo.DetailedState.FAILED)) {
//连接失败
LogUtils.logI("连接失败");
wifiLinkStateListener.connectFailed();
}
}
}
}
在这里注意对接口的定义必须声明为static类型,否则接口便是空的,暂时不知道这是为什么,如果有网友知道的话请告诉我。
(6)定义一个Wifi操作的相关类,这个类主要用来进行WIFI的相关操作,例如打开/关闭WIFI开关,扫描附近WIFI等
public class WifiLinkManager {
private WifiManager wifiManager;
public static final int SECURITY_WEP = 3;//WEP
public static final int SECURITY_WPA = 2;//WPA/WPA2
public static final int SECURITY_WPA_PSK = 1;//WPA-PSK/WPA2-PSK
public static final int SECURITY_NONE = 0;//没有密码
public WifiLinkManager(Context context) {
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
//获取最新的扫描结果
public List<ScanResult> getScanWifiList() {
return wifiManager.getScanResults();
}
//查看当前的wifi是否可用
public boolean checkWifiEnable() {
return wifiManager.isWifiEnabled();
}
//设置wifi是否可用
public boolean setWifiEnable(boolean enable) {
return wifiManager.setWifiEnabled(enable);
}
//开启扫描
public boolean startScanWifi() {
return wifiManager.startScan();
}
//获取当前连接到的wifi信息
public WifiInfo getConnectWifi() {
return wifiManager.getConnectionInfo();
}
//获取当前连接到的wifi的名字
public String getConnectWifiName() {
WifiInfo wifiInfo = getConnectWifi();
if (wifiInfo != null) {
return wifiInfo.getSSID();
}
return null;
}
//连接wifi
public boolean connectWifi(int netId) {
return wifiManager.enableNetwork(netId, true);
}
//删除一个已经配置好的wifi
public boolean deleteWifiInfo(String ssid) {
for (WifiConfiguration c : getConfigurationWifiList()) {
if (c.SSID.equals("\"" + ssid + "\"")) {
return wifiManager.removeNetwork(c.networkId);
}
}
return false;
}
//添加一个wifi网络
public int addWifiConfiguration(WifiConfiguration wifiConfiguration) {
return wifiManager.addNetwork(wifiConfiguration);
}
//获取已经保存的wifi列表
public List<WifiConfiguration> getConfigurationWifiList() {
return wifiManager.getConfiguredNetworks();
}
//判断一个wifi是否保存
public int checkWifiConfiguration(String ssid) {
List<WifiConfiguration> wifiConfigurationList = getConfigurationWifiList();
for (WifiConfiguration wifiConfiguration : wifiConfigurationList) {
if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
return wifiConfiguration.networkId;
}
}
return -1;
}
//获取加密方式
private int getSecurityType(String capabilities) {
if (capabilities.contains("WEP")) {
return SECURITY_WEP;
} else if (capabilities.contains("WPA")) {
if (capabilities.contains("PSK"))
return SECURITY_WPA_PSK;
return SECURITY_WPA;
} else {
return SECURITY_NONE;
}
}
//配置一个将要连接的wifi,配置成功返回netid
public int configWifi(ScanResult scanResult, String password) {
int result = -1;
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = "\"" + scanResult.SSID + "\"";
wifiConfiguration.hiddenSSID = false;
wifiConfiguration.status = WifiConfiguration.Status.ENABLED;
switch (getSecurityType(scanResult.capabilities)) {
case SECURITY_NONE:
wifiConfiguration.wepKeys[0] = "\"" + password + "\"";
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfiguration.wepTxKeyIndex = 0;
break;
case SECURITY_WEP:
wifiConfiguration.wepKeys[0] = "\"" + password + "\"";
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfiguration.wepTxKeyIndex = 0;
break;
case SECURITY_WPA:
case SECURITY_WPA_PSK:
wifiConfiguration.preSharedKey = "\"" + password + "\"";
break;
}
result = addWifiConfiguration(wifiConfiguration);
return result;
}
}
好了,到这里WIFI操作相关需要的操作就全部定义完了,在使用的时候,首先将接口定义出来以便能够接收到接口回调的数据:
wifiChangeBroadcast = new WifiChangeBroadcast();
wifiChangeBroadcast.setWifiLinkStateListener(this);
其次需要对WIFI执行相关操作的时候,声明WifiLinkManager类,通过这个类中的方法去执行相关操作:
wifiLinkManager = new WifiLinkManager(this);
到这里,所有的WIFI操作流程就全部执行完毕了,大概就是如下的操作
①WifiLinkManager类提供了相关wifi操作的方法,例如打开,关闭,扫描WIFI,可以通过这个类中的方法去发出相关对WIFI操作的指令
②WifiChangeBroadcast主要用来监听系统发出的广播,当wifi的状态改变之后,系统会发出相关广播,这个类会接收到系统发出的广播
③WifiLinkStateListener是一个接口,定义了相关的方法,当WifiChangeBroadcast接收到wifi状态改变的广播之后,会将不同的状态处理之后通过接口回调给其它类,其它类根据不同的wifi状态做出相关操作。