1.添加权限
<!-- wifi相关 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
2.获取wifi列表
(1) 获取wifiManager
wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
(2)注册wifi扫描广播
myWifiScanReceiver=new MyWifiScanReceiver();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mContext.registerReceiver(myWifiScanReceiver,intentFilter);
private class MyWifiScanReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ArrayList<ScanResult> list; //存放周围wifi热点对象的列表
list = (ArrayList<ScanResult>) wifiManager.getScanResults();
ArrayList<ScanResult> list_new = new ArrayList<>();
for(ScanResult result:list){
list_new.add(result);
}
list_new=sortByLevel(list_new);
wifiListInter.getWifiList(list_new);
try {
mContext.unregisterReceiver(myWifiScanReceiver);
}catch (Exception e){
}
}
}
此处的wifi列表,是自己手动扫描,然后监听扫描结果来获取的,比较最新的列表,当然,你也可以直接调用WifiManager的getScanResults()方法直接获取上次扫描到的wifi列表信息。
wifiManager.startScan();
3.将获取到的wifi列表,按照强度由高到低排序
这里的等级可以根据自己的需求设置等级数
private ArrayList<ScanResult> sortByLevel(ArrayList<ScanResult> list) {
Collections.sort(list, new Comparator<ScanResult>() {
@Override
public int compare(ScanResult scanResult, ScanResult t1) {
int i = wifiManager.calculateSignalLevel(t1.level,4)- wifiManager.calculateSignalLevel(scanResult.level,4);
return i;
}
});
return list;
}
4.获取wifi类别
public static final int WIFICIPHER_NOPASS = 0;
public static final int WIFICIPHER_WEP = 1;
public static final int WIFICIPHER_PSK = 2;
public static final int WIFICIPHER_EAP = 3;
public static final int WIFICIPHER_WAPI_PSK = 4;
public static final int WIFICIPHER_WAPI_CERT = 5;
public static int getSecurityType(ScanResult result) {
if (result.capabilities.contains("WAPI-PSK")) {
/* WAPI_PSK */
return WIFICIPHER_WAPI_PSK;
} else if (result.capabilities.contains("WAPI-CERT")) {
/* WAPI_CERT */
return WIFICIPHER_WAPI_CERT;
} else if (result.capabilities.contains("WEP")) {
return WIFICIPHER_WEP;
} else if (result.capabilities.contains("PSK")) {
return WIFICIPHER_PSK;
} else if (result.capabilities.contains("EAP")) {
return WIFICIPHER_EAP;
}
return WIFICIPHER_NOPASS;
}
5.连接wifi
public static void connectingWifi(Context context,String SSID, String password, int type){
mWifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE); //获得系统wifi服务
mWifiManager.setWifiEnabled(true);
mWifiManager.disconnect();
WifiList wifiList = new WifiList(context);
ArrayList<ScanResult> wifi_list = wifiList.getWifiList();
for(ScanResult result:wifi_list){
Log.e(TAG,"result:"+result.SSID+"");
if(result.SSID.equals(SSID)){
type = getSecurityType(result);
Log.e(TAG,"result:"+type+"");
}
}
//createWifiConfig主要用于构建一个WifiConfiguration,代码中的例子主要用于连接不需要密码的Wifi
//WifiManager的addNetwork接口,传入WifiConfiguration后,得到对应的NetworkId
Log.e(TAG, "SSID: " + SSID+"|||password:"+password+"|||type:"+type);
final WifiConfiguration wifiConfig =getWifiConfiguration(mWifiManager,SSID,password, type);
Log.e(TAG, "wifiConfig: " + wifiConfig);
int netId = mWifiManager.addNetwork(wifiConfig);
Log.e(TAG, "netId: " + netId);
//WifiManager的enableNetwork接口,就可以连接到netId对应的wifi了
//其中boolean参数,主要用于指定是否需要断开其它Wifi网络
boolean enable = mWifiManager.enableNetwork(netId, true);
Log.e(TAG, "enable: " + enable);
is_Success = enable;
//可选操作,让Wifi重新连接最近使用过的接入点
//如果上文的enableNetwork成功,那么reconnect同样连接netId对应的网络
//若失败,则连接之前成功过的网络
if(!enable){
boolean reconnect = mWifiManager.reconnect();
Log.e(TAG, "reconnect: " + reconnect);
}
}
6.获取所连接wifi的链接信息wifiConfiguration
public static WifiConfiguration getWifiConfiguration(WifiManager wifiManager, String ssid, String password, int type) {
List<WifiConfiguration> wifiConfigList = wifiManager.getConfiguredNetworks();
if (wifiConfigList != null) {
for (WifiConfiguration wifiConfig : wifiConfigList) {
String new_SSID = null;
Log.e("new_SSID","SSID"+wifiConfig.SSID);
if(wifiConfig.SSID!=null&&wifiConfig.SSID.length()>3){
new_SSID= wifiConfig.SSID.substring(1,wifiConfig.SSID.length()-1);
}
Log.e("new_SSID","new_SSID"+new_SSID);
Log.e("new_SSID","ssid"+ssid);
if (new_SSID!=null&&new_SSID.trim().equals(ssid.trim())) {
Log.e("removeNetwork","removeNetwork"+wifiConfig.SSID+":::"+wifiConfig.networkId);
boolean isSuccess = wifiManager.removeNetwork(wifiConfig.networkId);
Log.e("removeNetwork","isSuccess:"+isSuccess);
wifiManager.saveConfiguration();
break;
}
}
}
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + ssid + "\"";
if(type == WIFICIPHER_NOPASS) {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
} else if(type == WIFICIPHER_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;
} else if(type == WIFICIPHER_PSK) {
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.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
} else if (type == WIFICIPHER_EAP) {
}
return config;
}
7.监听wifi链接状态
public void registerReceiver(Context context){
if (!isRegisterReceiver){
isRegisterReceiver = true;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(EXIT_ACTION);
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
context.registerReceiver(WifiReceiver.this,intentFilter);
}
}
public void unRegisterReceiver(Context context){
if (isRegisterReceiver){
isRegisterReceiver = false;
context.unregisterReceiver(WifiReceiver.this);
}
}
这里的回调响应事件,在实际开发中,重新链接其他网络,监听NETWORK_STATE_CHANGED_ACTION事件时,直接判断为已连接,所以,此处我们增加了一个is_Success的判断值,这个值 是在第五步的wifiManager.addNetWork()方法的成功返回值。
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mobileInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo activeInfo = manager.getActiveNetworkInfo();
if (mobileInfo != null && activeInfo != null && wifiInfo != null){
// Toast.makeText(context, "mobile:"+mobileInfo.isConnected()+"\n"+"wifi:"+wifiInfo.isConnected()
// +"\n"+"active:"+activeInfo.getTypeName(), Toast.LENGTH_LONG).show();
}
switch (intent.getAction()){
case WifiManager.NETWORK_STATE_CHANGED_ACTION:
LogUtils.e("WifiReceiver","网络状态改变");
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (null != info) {
NetworkInfo.State state = info.getState();
boolean isConnected = state == NetworkInfo.State.CONNECTED;
LogUtils.e("WifiReceiver", WifiUtil.is_Success+"isConnected:"+isConnected+"::"+wifiInfo.isConnected());
if (isConnected&&WifiUtil.is_Success) {
LogUtils.e("WifiReceiver", "connectWiFiSuccess");
if (mCallBack != null) {
mCallBack.connectWiFiSuccess();
WifiUtil.is_Success = false;
}
}
}
break;
case WifiManager.SUPPLICANT_STATE_CHANGED_ACTION:
int linkWifiResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 123);
LogUtils.e("linkWifiResult",linkWifiResult+"");
if (linkWifiResult == WifiManager.ERROR_AUTHENTICATING) {
LogUtils.e("WifiReceiver","密码错误");
if(mCallBack!=null){
mCallBack.connectWiFiFailed();
}
}
break;
case WifiManager.WIFI_STATE_CHANGED_ACTION:
WifiManager mWm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//获取当前的wifi状态int类型数据
int mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
switch (mWifiState ) {
case WifiManager.WIFI_STATE_ENABLED:
//已打开
break;
case WifiManager.WIFI_STATE_DISABLED:
//已关闭
if(!mWm.isWifiEnabled()){
mWm.setWifiEnabled(true);
}
break;
}
break;
}
}
8.wifi相关的其他方法
(1)判断wifi是不是5G网络(部分手机不支持5G)
/**
* 判断wifi是否为5G
* @param freq
* @return
*/
public static boolean is5GHz(int freq) {
return freq > 4900 && freq < 5900;
}
(2)判断手机是否开启了热点(如果开启了热点,则不让打开wifi)
/**判断热点开启状态*/
public boolean isWifiApEnabled() {
return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
}
public enum WIFI_AP_STATE {
WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_FAILED
}
private WIFI_AP_STATE getWifiApState(){
int tmp;
try {
Method method = wifiManager.getClass().getMethod("getWifiApState");
tmp = ((Integer) method.invoke(wifiManager));
// Fix for Android 4
if (tmp > 10) {
tmp = tmp - 10;
}
return WIFI_AP_STATE.class.getEnumConstants()[tmp];
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
}
}
(3)在Android6.0之后,不同应用间,不能够修改其他应用设置的wifi。即 removeNetWork()方法返回false 这个问题 普通应用开发 目前没有找到解决办法。 但是通过查看Settings源码发现,Settings是用过forgett()方法 来删除wifi信息的。 具体的 可以查看系统源码。但是调用forget方法,必须在系统编译下 才能够使用 所以 并不适用于普通的app开发
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiServiceImpl 等相关代码
wifiManager.forget(accessPoint.getConfig().networkId, null /* listener */);