目录
1.网上搜集的一些资料
监听Wifi连接
https://www.jianshu.com/p/2a7dcc79a7b4
https://blog.csdn.net/lizhenmingdirk/article/details/19817101
获取Wifi列表
https://juejin.im/post/5d1356166fb9a07ed4411173
https://blog.csdn.net/liuxiaopang520/article/details/89187082
Wifi扫描结果ScanResult属性详解
https://blog.csdn.net/male09/article/details/70792657/
获取Wifi的加密方式
https://blog.csdn.net/fenggit/article/details/47187227
获取Wifi信号强度
https://blog.csdn.net/qq_26981913/article/details/52276732/
连接到指定的Wifi
https://blog.csdn.net/qq_36503704/article/details/82744616
判断Wifi连接密码错误
https://ask.csdn.net/questions/692936
https://blog.csdn.net/lepaitianshi/article/details/83111723
进入Wifi开关设置页面
https://www.jianshu.com/p/95c839a9654b
2.我的代码是怎么写的
首先,申请权限
<!-- WIFI-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 获取WIFI列表需要位置权限,即使后面会动态申请,这里也要注册,否则手机不提示。-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
开始撸代码
1)监听Wifi已经连接
先注册广播
if(wifiReceiver == null){
filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
wifiReceiver = new WifiReceiver(webViewFragment);
}
broadcastRegistHelper.setWebViewFragment(webViewFragment);
broadcastRegistHelper.regist(wifiReceiver,filter);
解析广播
class WifiReceiver extends BroadcastReceiver {
WebViewFragment webViewFragment;
public WifiReceiver(WebViewFragment webViewFragment) {
this.webViewFragment = webViewFragment;
}
@Override
public void onReceive(Context context, Intent intent) {
//wifi连接上与否
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {
Logger.e(TAG, "wifi断开");
WxAPIConfig.WiFi.isOnWifiConnectedCallBackOnce = false;
wxWifiInfo = null;
} else if (info.getState().equals(NetworkInfo.State.CONNECTED)) {
if(WxAPIConfig.WiFi.isOnWifiConnectedCalled){
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
//获取当前wifi名称
Logger.e(TAG, "连接到网络 " + wifiInfo.getSSID());
wxWifiInfo = new WxWifiInfo();
wxWifiInfo.setSSID(wifiInfo.getSSID());
wxWifiInfo.setBSSID(wifiInfo.getBSSID());
wxWifiInfo.setSecure(WifiUtil.isSecure(wifiManager,wifiInfo.getSSID()));
wxWifiInfo.setSignalStrength(wifiManager.calculateSignalLevel(wifiInfo.getRssi(),100));
//只有startWifi被调用了,才去回复,否则只是缓存。
if(WxAPIConfig.WiFi.isWifiStartCalled){
callback(webViewFragment);
}
}
}
}
}
}
2)获取Wifi列表
首先要动态申请Manifest.permission.ACCESS_COARSE_LOCATION权限,然后开始获取Wifi列表。
private void getWifiList(WebViewFragment webViewFragment,Plugin.PluginCallback pluginCallback) {
if(WxAPIConfig.WiFi.isWifiStartCalled && WxAPIConfig.WiFi.isOnGetWifiListCalled){
List<ScanResult> scanResults = wifiManager.getScanResults();
List<WxWifiInfo> result = new ArrayList<>();
for (ScanResult item : scanResults){
WxWifiInfo wxWifiInfo = new WxWifiInfo();
wxWifiInfo.setSSID(item.SSID);
wxWifiInfo.setBSSID(item.BSSID);
wxWifiInfo.setSecure(WifiUtil.isSecure(wifiManager,item));
wxWifiInfo.setSignalStrength(wifiManager.calculateSignalLevel(item.level,100));
// wxWifiInfo.setSignalStrength(item.level);
result.add(wxWifiInfo);
Logger.e(TAG,"扫描到的wifi:" + wxWifiInfo);
}
Map map = new HashMap<>();
map.put("success", true);
map.put("complete", true);
map.put("wifiList", result);
webViewFragment.executeEvent(JsCallBackKeys.ON_GET_WIFI_LIST, map,null);
}else{
Logger.e(TAG,"获取WIFI列表监听没有打开,获取WIFI列表干球啊.");
}
responseSuccess(pluginCallback);
}
3)获取已经连接的Wifi
先打开定位开关并且申请Manifest.permission.ACCESS_COARSE_LOCATION权限
判断GPS是否开启的方法
public static boolean isOPen(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
打开定位服务开关
//初始化接口是否调用
boolean gpsIsOpen = GpsUtil.isOPen(com.gen.mh.webapp_extensions.WebApplication.getInstance().getApplication());
if (gpsIsOpen) {
doAfterGpsOpened(webViewFragment, pluginCallback);
} else {
//提示用户打开定位
//对于没有系统签名,可能需要人工干预开启gps。
new AlertDialog.Builder(webViewFragment.getActivity())
.setTitle("提示")
.setMessage("获取已经连接的Wifi需要打开定位功能")
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Logger.e(TAG, "用户拒绝了打开位置权限");
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12006);
}
})
.setPositiveButton("前往设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
webViewFragment.addResultListsners(new ActivityResultListener() {
@Override
public boolean onSdkActivityResult(int requestCode, int resultCode, Intent intent) {
// if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_OPEN_GPS) {
// startDiscovery(webViewFragment, paramsBean, pluginCallback, mBluetoothAdapter, leScanCallback);
// return false;
// }
//上面的判断方法有BUG,在YuLong手机上,即使用户打开了定位服务,resultCode返回的并不是 Activity.RESULT_OK
//那就再判断一次呐,机智如我!
if(REQUEST_CODE_OPEN_GPS == requestCode){
boolean gpsIsOpen = GpsUtil.isOPen(WebApplication.getInstance().getApplication());
if(gpsIsOpen){
doAfterGpsOpened(webViewFragment, pluginCallback);
return false;
}
Logger.e(TAG, "用户拒绝了打开位置权限");
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12006);
}
return false;
}
});
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
webViewFragment.startActivityForResult(intent, REQUEST_CODE_OPEN_GPS);
}
})
.setCancelable(false)
.show();
}
申请Manifest.permission.ACCESS_COARSE_LOCATION权限
获取已经连接的Wifi
private void getConnectedWifi(Plugin.PluginCallback pluginCallback) {
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if(wifiInfo != null && !wifiInfo.getSSID().equals("<unknown ssid>")){
//获取当前wifi名称
Logger.e(TAG, "已经连接到网络 " + wifiInfo.getSSID());
if(WxAPIConfig.WiFi.isWifiStartCalled){
Logger.e(TAG, "回调给JS");
WxWifiInfo wxWifiInfo = new WxWifiInfo();
wxWifiInfo.setSSID(wifiInfo.getSSID());
wxWifiInfo.setBSSID(wifiInfo.getBSSID());
wxWifiInfo.setSecure(WifiUtil.isSecure(wifiManager,wifiInfo.getSSID()));
wxWifiInfo.setSignalStrength(wifiManager.calculateSignalLevel(wifiInfo.getRssi(),100));
map.clear();
map.put("wifi", wxWifiInfo);
responseSuccess(pluginCallback,map);
return;
}
}else{
Logger.e(TAG, "未连接到任何的网络");
}
responseFailure(pluginCallback,ErrorPool.WifiError.createOtherTypeError(ErrorPool.WifiError.CODE_12010,"getConnectedWifi:fail:currentWifi is null"));
}
3)连接到指定Wifi
这个只所以放到最后说,是由于坑最多。
1)准备连接的条件
先过滤非法的参数
/**
* 非法SSID判断
*/
if(paramsBean == null || TextUtils.isEmpty(paramsBean.getSSID())){
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12008);
return;
}
/**
* 判断是否是重复连接
*/
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if(wifiInfo != null && !wifiInfo.getSSID().equals("<unknown ssid>")){
//获取当前wifi名称
Logger.e(TAG, "已经连接到网络 " + wifiInfo.getSSID());
if(wifiInfo.getSSID().equals(paramsBean.getSSID()) || wifiInfo.getBSSID().equals(paramsBean.getBSSID())){
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12004);
return;
}
}
/**
* 密码小于8位,认为密码不正确。
*/
if(TextUtils.isEmpty(paramsBean.getPassword()) || paramsBean.getPassword().length() < 8){
Log.e(TAG, "密码位于小于8,认为密码错误。");
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12002);
return;
}
打开Wifi开关
boolean wifiEnabled = wifiManager.isWifiEnabled();
if(wifiEnabled){
doAfterWifiOpened(webViewFragment, paramsBean, pluginCallback);
}else{
//提示用户打开Wifi开关
new AlertDialog.Builder(webViewFragment.getActivity())
.setTitle("提示")
.setMessage("连接Wifi需要先打开Wifi开关")
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Logger.e(TAG, "用户拒绝了打开Wifi开关");
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12005);
}
})
.setPositiveButton("前往设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
webViewFragment.addResultListsners(new ActivityResultListener() {
@Override
public boolean onSdkActivityResult(int requestCode, int resultCode, Intent intent) {
// if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_OPEN_GPS) {
// startDiscovery(webViewFragment, paramsBean, pluginCallback, mBluetoothAdapter, leScanCallback);
// return false;
// }
//上面的判断方法有BUG,在YuLong手机上,即使用户打开了定位服务,resultCode返回的并不是 Activity.RESULT_OK
//那就再判断一次呐,机智如我!
if(requestCode == REQUEST_CODE_OPEN_WIFI){
boolean wifiEnabled = wifiManager.isWifiEnabled();
if(wifiEnabled){
doAfterWifiOpened(webViewFragment, paramsBean, pluginCallback);
return false;
}
Logger.e(TAG, "用户拒绝了打开Wifi开关");
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12005);
}
return false;
}
});
Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
webViewFragment.startActivityForResult(intent, REQUEST_CODE_OPEN_WIFI);
}
})
.setCancelable(false)
.show();
}
动态申请权限Manifest.permission.ACCESS_COARSE_LOCATION
连接到指定的Wifi
private void connectWifi(ConnectWifiParamsBean paramsBean, Plugin.PluginCallback pluginCallback) {
if(wifiConnectReceiver == null){
wifiConnectReceiver = new WifiConnectReceiver();
intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); //连接时密码是否正确监听
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); //连接时密码是否正确监听
}
wifiConnectReceiver.attachParams(pluginCallback,paramsBean);
broadcastRegistHelper.regist(wifiConnectReceiver,intentFilter);
boolean result = WifiUtil.connectWifi(wifiManager, paramsBean);
Logger.e(TAG, "连接结果:" + result);
if(result == false){
responseFailure(pluginCallback,ErrorPool.WifiError.CODE_12002);
setLockResponse(true);
}
}
连接的具体代码贴出如下:
public class WifiUtil {
private static final String TAG = "WifiUtil";
/**
* 判断Wifi是否安全,适用于WIFI扫描列表。
* @param wifiManager
* @param scanResult
* @return
*/
public static boolean isSecure(WifiManager wifiManager, ScanResult scanResult) {
if (!TextUtils.isEmpty(scanResult.SSID)) {
String capabilities = scanResult.capabilities;
if (!TextUtils.isEmpty(capabilities)) {
if (capabilities.contains("WPA") || capabilities.contains("wpa")) {
Logger.e("river", "wpa");
} else if (capabilities.contains("WEP") || capabilities.contains("wep")) {
Logger.e("river", "wep");
} else {
Logger.e("river", "no");
return false;
}
}
}
return true;
}
/**
* 通用,包括WIFI扫描列表和已经连接的WIFI。
* @param wifiManager
* @param ssid
* @return
*/
public static boolean isSecure(WifiManager wifiManager, String ssid) {
List<ScanResult> list = wifiManager.getScanResults();
for (ScanResult scResult : list) {
if (!TextUtils.isEmpty(scResult.SSID) && scResult.SSID.equals(ssid)) {
String capabilities = scResult.capabilities;
Logger.e("river","capabilities=" + capabilities);
if (!TextUtils.isEmpty(capabilities)) {
if (capabilities.contains("WPA") || capabilities.contains("wpa")) {
Logger.e("river", "wpa");
return true;
} else if (capabilities.contains("WEP") || capabilities.contains("wep")) {
Logger.e("river", "wep");
return true;
} else {
Logger.e("river", "no");
return false;
}
}
}
}
return false;
}
/**
* 获取热点的加密类型
* @param wifiManager
* @param ssid
* @return
*/
public static int getSecureType(WifiManager wifiManager, String ssid) {
List<ScanResult> list = wifiManager.getScanResults();
for (ScanResult scResult : list) {
if (!TextUtils.isEmpty(scResult.SSID) && scResult.SSID.equals(ssid)) {
String capabilities = scResult.capabilities;
Logger.e("river","capabilities=" + capabilities);
if (!TextUtils.isEmpty(capabilities)) {
if (capabilities.contains("WPA") || capabilities.contains("wpa")) {
Logger.e("river", "wpa");
return 2;
} else if (capabilities.contains("WEP") || capabilities.contains("wep")) {
Logger.e("river", "wep");
return 1;
} else {
Logger.e("river", "no");
return 0;
}
}
}
}
return 0;
}
/**
* 获取WIFI的配置信息,参照{@link https://blog.csdn.net/qq_36503704/article/details/82744616}
* @param mWifiManager
* @param SSID
* @param password
* @param type
* @return
*/
public static WifiConfiguration configWifiInfo(WifiManager mWifiManager, String SSID, String password, int type) {
WifiConfiguration config = null;
if (mWifiManager != null) {
List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig == null) continue;
if (existingConfig.SSID.equals("\"" + SSID + "\"") /*&& existingConfig.preSharedKey.equals("\"" + password + "\"")*/) {
config = existingConfig;
Logger.e("cz", "find a config," + config );
break;
}
}
}
if (config == null) {
config = new WifiConfiguration();
}
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
// 分为三种情况:0没有密码1用wep加密2用wpa加密
if (type == 0) {// WIFICIPHER_NOPASSwifiCong.hiddenSSID = false;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
} else if (type == 1) { // 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 == 2) { // WIFICIPHER_WPA
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;
}
return config;
}
/**
* 扫描指定的WIFI
* @param wifiManager
* @param connectWifiParamsBean
* @return
*/
public static ScanResult findWifi(WifiManager wifiManager,ConnectWifiParamsBean connectWifiParamsBean ){
List<ScanResult> scanResults = wifiManager.getScanResults();
for (ScanResult item : scanResults){
if(item.SSID.equals(connectWifiParamsBean.getSSID()) /*&& connectWifiParamsBean.getBSSID().equals(item.BSSID)*/){
Logger.e(TAG,"可以扫描到要连接的wifi,准备连接");
return item;
}
}
return null;
}
/**
* 连接到指定的WIFI
* @param wifiManager
* @param connectWifiParamsBean
* @return
*/
public static boolean connectWifi(WifiManager wifiManager, ConnectWifiParamsBean connectWifiParamsBean){
ScanResult wifi = findWifi(wifiManager, connectWifiParamsBean);
if(wifi == null){
Logger.e(TAG, "connectWifi: 未扫描到要连接的WIFI");
return false;
}
WifiConfiguration configuration = configWifiInfo(wifiManager, connectWifiParamsBean.getSSID(), connectWifiParamsBean.getPassword(), getSecureType(wifiManager,connectWifiParamsBean.getSSID()));
int netId = configuration.networkId;
Logger.e("cz", "connectWifi netId " + netId );
if (netId == -1) {
netId = wifiManager.addNetwork(configuration);
}
return wifiManager.enableNetwork(netId, true); //已经成功连接过并且记住密码的,直接就能连接上。
}
}
注意WifiUtil.connectWifi方法返回的结果为true并不代表wifi就连接成功,好像这个方法始终就是返回true。
解析前面注册的广播
@Override
public void onReceive(Context context, Intent intent) {
if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(intent.getAction())) {
//密码错误
int linkWifiResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1); //注意wifi开关没有打开 ,或者密码小于8位,或者wifi已经记住了。永远直接取的是defalutValue。
Logger.e(TAG, "linkWifiResult: " + linkWifiResult);
if (linkWifiResult == WifiManager.ERROR_AUTHENTICATING) { //TODO 有很小的机率,明明密码正确也会报错误。
Logger.e(TAG, "onReceive: 密码错误" );
responseFailure(pluginCallback, ErrorPool.WifiError.CODE_12002);
setLockResponse(true);
return;
}
} else if(WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())){ //wifi是否连接.
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
//判断是否连接到了指定的网络
if(info.getState().equals(NetworkInfo.State.CONNECTED)){
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if(wifiInfo != null && !wifiInfo.getSSID().equals("<unknown ssid>")){
//获取当前wifi名称
Logger.e(TAG, "连接到网络 " + wifiInfo.getSSID());
Logger.e(TAG, "指定要连接的网络 " + paramsBean.getSSID());
//由wifiInfo.getSSID()比paramsBean.getSSID()多了两个双引号,所以不能用equals判断。
if(wifiInfo.getSSID().contains(paramsBean.getSSID()) || paramsBean.getSSID().contains(wifiInfo.getSSID())){
responseSuccess(pluginCallback);
setLockResponse(true);
return;
}
}
}
}
}
连接wifi密码错误的判断:通过WifiManager.ERROR_AUTHENTICATING即可判断,但前提是这个Wifi之前从来没有连接过,否则即使密码输入啥
intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
都只会得到-1值。
至于已经连接过的Wifi,怎么判断密码输入错误,还请路过的高手指点一下。
如有疑惑或者好的建议,或者想纠正作者的博文,请联系如下
公众号:微信公众号搜索“修符道人”或者扫描下方二维码
微信号:XinYi1349308479
QQ邮箱:1349308479@qq.com
0 条评论