desc:wifi 设置

main
xiaowusky 2 years ago
parent 0a49b93b2a
commit 65d361cb77

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest android:sharedUserMaxSdkVersion="32"
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system"
package="com.yinuo.safetywatcher">
@ -23,6 +22,12 @@
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--wifi-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_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.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
@ -51,6 +56,7 @@
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
@ -80,7 +86,7 @@
android:name=".watcher.ui.SensorSettingActivity"
android:exported="false"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan"/>
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".watcher.ui.QueryDataActivity"
android:exported="false"
@ -111,17 +117,22 @@
android:screenOrientation="landscape" />
<activity
android:name=".player.ProVideoActivity"
android:screenOrientation="landscape"
android:exported="false"
android:screenOrientation="landscape"
android:theme="@style/FullscreenTheme" />
<activity
android:name=".watcher.ui.ChartActivity"
android:exported="true"
android:exported="false"
android:screenOrientation="landscape" />
<activity
android:name=".watcher.ui.GasListActivity"
android:exported="true"
android:exported="false"
android:screenOrientation="landscape" />
<activity
android:name=".watcher.wifi.ui.GlobalMonitorActivity"
android:exported="false"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan"/>
</application>
</manifest>

@ -1,16 +1,17 @@
package com.yinuo.safetywatcher.watcher
import com.common.commonlib.CommonApplication
import com.lztek.toolkit.Lztek
import com.yinuo.safetywatcher.TestUtils
import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.dao.WarningDao
import com.common.commonlib.db.entity.Warning
import com.yinuo.safetywatcher.TestUtils
import com.yinuo.safetywatcher.watcher.constant.CAMERA_DNS
import com.yinuo.safetywatcher.watcher.constant.CAMERA_GATEWAY
import com.yinuo.safetywatcher.watcher.constant.CAMERA_IP
import com.yinuo.safetywatcher.watcher.constant.CAMERA_NETMASK
import com.yinuo.safetywatcher.watcher.utils.LztekUtil
import com.yinuo.safetywatcher.watcher.wifi.WiFiConfig
import com.yinuo.safetywatcher.watcher.wifi.WiFiModule
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@ -23,10 +24,19 @@ class App : CommonApplication() {
super.onCreate()
LztekUtil.setObject(Lztek.create(this))
ipConfig()
wifiConfig()
tryFixDbData()
TestUtils.insertData()
}
private fun wifiConfig() {
//初始化
val config: WiFiConfig = WiFiConfig.Builder()
.setTimeOut(1000 * 20)
.build()
WiFiModule.getInstance().setConfig(config).init(this)
}
private fun ipConfig() {
LztekUtil.getLztek()
?.setEthIpAddress(CAMERA_IP, CAMERA_NETMASK, CAMERA_GATEWAY, CAMERA_DNS)

@ -10,6 +10,7 @@ import com.yinuo.safetywatcher.databinding.ActivityNetSettingBinding
import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity
import com.yinuo.safetywatcher.watcher.utils.NetworkStatsHelper
import com.yinuo.safetywatcher.watcher.utils.TrafficFormat
import com.yinuo.safetywatcher.watcher.wifi.ui.GlobalMonitorActivity
class NetSettingActivity : NoOptionsActivity() {
@ -29,8 +30,8 @@ class NetSettingActivity : NoOptionsActivity() {
override fun initView() {
mBinding.apply {
itemWifi.setOnClickListener {
Intent.ACTION_FACTORY_TEST
startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
// startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
startActivity(Intent(this@NetSettingActivity, GlobalMonitorActivity::class.java))
}
}

@ -12,7 +12,7 @@ import com.yinuo.safetywatcher.watcher.ui.view.ConfirmDialog
class SettingActivity : NoOptionsActivity() {
private val resetFactoryDialog by lazy {
ConfirmDialog() {
ConfirmDialog(getString(R.string.confirm_clear_data_tip)) {
resetEverything()
}
}

@ -71,15 +71,10 @@ class CommonTopBar : LinearLayout {
private val wifiCallback = object : WifiHelper.OnWifiLevelCallback {
override fun onEnable(enable: Boolean) {
Log.i(this@CommonTopBar.javaClass.name, "wifiCallback onEnable = $enable")
// if (enable) {
// mBinding?.wifi?.visibility = VISIBLE
// } else {
// mBinding?.wifi?.visibility = GONE
// }
if (!enable) {
mBinding?.wifi?.visibility = GONE
} else {
mBinding?.wifi?.visibility = VISIBLE
// mBinding?.wifi?.visibility = VISIBLE
}
}

@ -12,7 +12,7 @@ import com.yinuo.safetywatcher.R
import com.yinuo.safetywatcher.databinding.LayoutConfirmDialogBinding
class ConfirmDialog(
private val tipResID: Int = R.string.confirm_clear_data_tip,
private val tipStr: String = "",
private val onConfirmClick: (() -> Unit?)? = null
) :
DialogFragment() {
@ -25,7 +25,7 @@ class ConfirmDialog(
savedInstanceState: Bundle?
): View? {
dialogBinding = LayoutConfirmDialogBinding.inflate(inflater, container, false)
dialogBinding!!.tip.text = getString(tipResID)
dialogBinding!!.tip.text = tipStr
dialogBinding!!.tvConfirm.setOnClickListener {
onConfirmClick?.invoke()
}

@ -0,0 +1,33 @@
package com.yinuo.safetywatcher.watcher.wifi;
/**
* WiFi
*/
public class WiFiConfig {
//默认超时时间
private static final long DEFAULT_TIME_OUT = 1000 * 15;
public long timeOut = DEFAULT_TIME_OUT;
private WiFiConfig() {
}
public static class Builder {
private WiFiConfig config;
public Builder() {
config = new WiFiConfig();
}
public Builder setTimeOut(long time) {
config.timeOut = time;
return this;
}
public WiFiConfig build() {
return config;
}
}
}

@ -0,0 +1,203 @@
package com.yinuo.safetywatcher.watcher.wifi;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiDirectConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiDisableAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiNormalConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiRemoveAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiScanAction;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ConnectWiFiActionListener;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.RemoveWiFiActionListener;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ScanWiFiActionListener;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiListener;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiCipherType;
import com.yinuo.safetywatcher.watcher.wifi.utils.WiFiLogUtils;
import com.yinuo.safetywatcher.watcher.wifi.utils.WiFiModuleService;
/**
* WiFi使{@link #init}
*/
public class WiFiModule {
private WiFiModuleService mWiFiSupportService;
private WiFiConfig mWiFiConfig = new WiFiConfig.Builder().build();
private boolean isInit = false;
private WiFiModule() {
}
private static class WiFiSupportInner {
private static WiFiModule instance = new WiFiModule();
}
public static WiFiModule getInstance() {
return WiFiModule.WiFiSupportInner.instance;
}
/**
* ,{@link #init }
*/
public WiFiModule setConfig(WiFiConfig config) {
this.mWiFiConfig = config;
return this;
}
/**
*
*/
public void init(Context context) {
if (isInit) {
return;
}
this.mWiFiSupportService = new WiFiModuleService(context);
WiFiLogUtils.d("初始化");
isInit = true;
}
/**
* WiFi
*
* @param key
* @param listener
*/
public void addWiFiListener(String key, WiFiListener listener) {
if (null == mWiFiSupportService) {
WiFiLogUtils.d("请先初始化!");
return;
}
mWiFiSupportService.addWiFiListener(key, listener);
}
/**
* WiFi
*
* @param key
*/
public void removeWiFiListener(String key) {
if (null == mWiFiSupportService) {
WiFiLogUtils.d("请先初始化!");
return;
}
mWiFiSupportService.removeWiFiListener(key);
}
/**
* WiFi
*/
public void startScan() {
this.startScan(null);
}
/**
* WiFi
*/
public void startScan(@Nullable ScanWiFiActionListener listener) {
if (null == mWiFiSupportService) {
WiFiLogUtils.d("请先初始化!");
return;
}
WiFiScanAction action = new WiFiScanAction(listener);
mWiFiSupportService.addAction(action);
}
/**
* WiFi
*/
public void disableWifi() {
if (null == mWiFiSupportService) {
WiFiLogUtils.d("请先初始化!");
return;
}
WiFiDisableAction action = new WiFiDisableAction();
mWiFiSupportService.addAction(action);
}
/**
* WiFi
*/
public void connectWiFi(String SSID, WiFiCipherType type, @Nullable String password) {
this.connectWiFi(SSID, type, password, null);
}
/**
* WiFi
*/
public void connectWiFi(String SSID, WiFiCipherType type, @Nullable String password, @Nullable ConnectWiFiActionListener listener) {
if (null == mWiFiSupportService) {
WiFiLogUtils.d("请先初始化!");
return;
}
WiFiNormalConnectAction action = new WiFiNormalConnectAction(SSID, type, password, listener);
action.timeout = (null == mWiFiConfig) ? -1 : mWiFiConfig.timeOut;
mWiFiSupportService.addAction(action);
}
/**
* WiFi
*/
public void connectWiFi(WifiConfiguration configuration) {
this.connectWiFi(configuration, null);
}
/**
* WiFi
*/
public void connectWiFi(WifiConfiguration configuration, @Nullable ConnectWiFiActionListener listener) {
if (null == mWiFiSupportService) {
return;
}
String SSID = configuration.SSID;
int size = SSID.length();
SSID = SSID.substring(1, size - 1);
WiFiDirectConnectAction action = new WiFiDirectConnectAction(SSID, configuration, listener);
action.timeout = mWiFiConfig.timeOut;
mWiFiSupportService.addAction(action);
}
/**
* WiFi
*/
public void removeWiFi(final String SSID) {
this.removeWiFi(SSID, null);
}
/**
* WiFi
*/
public void removeWiFi(final String SSID, @Nullable RemoveWiFiActionListener listener) {
if (null == mWiFiSupportService) {
WiFiLogUtils.d("请先初始化!");
return;
}
WiFiRemoveAction action = new WiFiRemoveAction(SSID, listener);
mWiFiSupportService.addAction(action);
}
/**
*
*/
public void destroy() {
if (null != mWiFiSupportService) {
mWiFiSupportService.destroy();
}
isInit = false;
mWiFiSupportService = null;
}
}

@ -0,0 +1,18 @@
package com.yinuo.safetywatcher.watcher.wifi.info;
import android.net.wifi.WifiConfiguration;
/**
* WiFi
*/
public class WiFiCreateConfigStatusInfo {
public String SSID;
public WifiConfiguration configuration;
public boolean isSuccess;
public boolean isSuccess() {
return isSuccess && null != configuration;
}
}

@ -0,0 +1,11 @@
package com.yinuo.safetywatcher.watcher.wifi.info;
/**
* WiFi
*/
public class WiFiRemoveStatusInfo {
public String SSID;
public boolean isSuccess;
}

@ -0,0 +1,105 @@
package com.yinuo.safetywatcher.watcher.wifi.info;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiCipherType;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectType;
/**
* WiFi
*/
public class WiFiScanInfo implements Comparable<WiFiScanInfo>, Parcelable {
//扫描结果
public ScanResult scanResult;
//连接过的WiFi配置可能为空
public WifiConfiguration configuration;
//WiFi型号强度(1~4)
public int level;
//连接状态0 未连接1 正在连接2 已连接
public int connectType = WiFiConnectType.DISCONNECTED.type;
@Override
public int compareTo(WiFiScanInfo o) {
//按照信号强度从大到小排序
return o.level - level;
}
@NonNull
@Override
public String toString() {
return "{" +
"\"SSID\":\"" + scanResult.SSID + "\"," +
"\"type\":" + getCipherType().ordinal() + "," +
"\"level\":" + level +
"}";
}
/**
* WiFi
*
* @return WiFiCipherType
*/
public WiFiCipherType getCipherType() {
if (null == scanResult) {
return WiFiCipherType.WIFI_CIPHER_INVALID;
}
String capabilities = scanResult.capabilities;
if (TextUtils.isEmpty(capabilities)) {
return WiFiCipherType.WIFI_CIPHER_INVALID;
}
if (capabilities.contains("WPA") || capabilities.contains("wpa") || capabilities.contains("WPA2") || capabilities.contains("WPS")) {
return WiFiCipherType.WIFI_CIPHER_WPA;
}
if (capabilities.contains("WEP") || capabilities.contains("wep")) {
return WiFiCipherType.WIFI_CIPHER_WEP;
}
return WiFiCipherType.WIFI_CIPHER_NO_PASS;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(this.scanResult, flags);
dest.writeParcelable(this.configuration, flags);
dest.writeInt(this.level);
dest.writeInt(this.connectType);
}
public WiFiScanInfo() {
}
protected WiFiScanInfo(Parcel in) {
this.scanResult = in.readParcelable(ScanResult.class.getClassLoader());
this.configuration = in.readParcelable(WifiConfiguration.class.getClassLoader());
this.level = in.readInt();
this.connectType = in.readInt();
}
public static final Parcelable.Creator<WiFiScanInfo> CREATOR = new Parcelable.Creator<WiFiScanInfo>() {
@Override
public WiFiScanInfo createFromParcel(Parcel source) {
return new WiFiScanInfo(source);
}
@Override
public WiFiScanInfo[] newArray(int size) {
return new WiFiScanInfo[size];
}
};
}

@ -0,0 +1,38 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
import androidx.annotation.NonNull;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
public abstract class IWiFiAction {
@Types.ActionStateType
private int actionState;
IWiFiAction() {
setState(Types.ActionStateType.WAITING);
}
private String getActionName() {
return getClass().getSimpleName();
}
public int getActionState() {
return actionState;
}
public void setState(@Types.ActionStateType int state) {
this.actionState = state;
}
public void end() {
this.actionState = Types.ActionStateType.END;
}
@NonNull
@Override
public String toString() {
return getActionName() + " | actionState:" + actionState;
}
}

@ -0,0 +1,70 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ConnectWiFiActionListener;
import com.yinuo.safetywatcher.watcher.wifi.utils.WiFiLogUtils;
import java.lang.ref.WeakReference;
/**
* WiFi
*/
public abstract class WiFiConnectAction extends IWiFiAction {
public String SSID;
public ConnectWiFiActionListener listener;
public long timeout = 1000 * 15;//超时时间默认15s
private WeakReference<Handler> mHandler;
private Runnable mDelayRunnable;
WiFiConnectAction(@NonNull String SSID, @Nullable ConnectWiFiActionListener listener) {
this.SSID = SSID;
this.listener = listener;
}
@Override
public void end() {
super.end();
stopDelayCheck();
}
/**
*
*/
public void startDelayCheck(Handler handler, Runnable runnable) {
this.mHandler = new WeakReference<>(handler);
this.mDelayRunnable = runnable;
try {
handler.postDelayed(runnable, this.timeout);
WiFiLogUtils.d("开启超时检测," + toString());
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
/**
*
*/
private void stopDelayCheck() {
try {
if (null == this.mDelayRunnable) {
return;
}
this.mHandler.get().removeCallbacks(this.mDelayRunnable);
this.mDelayRunnable = null;
WiFiLogUtils.d("超时检测关闭," + toString());
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
}

@ -0,0 +1,28 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
import android.net.wifi.WifiConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ConnectWiFiActionListener;
/**
*
*/
public class WiFiDirectConnectAction extends WiFiConnectAction {
public WifiConfiguration configuration;
public WiFiDirectConnectAction(@NonNull String SSID, @NonNull WifiConfiguration configuration, @Nullable ConnectWiFiActionListener listener) {
super(SSID, listener);
this.configuration = configuration;
}
@NonNull
@Override
public String toString() {
return super.toString() + " | " + SSID;
}
}

@ -0,0 +1,7 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
/**
* WiFi
*/
public class WiFiDisableAction extends IWiFiAction {
}

@ -0,0 +1,7 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
/**
* WiFi
*/
public class WiFiEnableAction extends IWiFiAction {
}

@ -0,0 +1,29 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ConnectWiFiActionListener;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiCipherType;
/**
* WiFi
*/
public class WiFiNormalConnectAction extends WiFiConnectAction {
public WiFiCipherType cipherType;
public String password;
public WiFiNormalConnectAction(@NonNull String SSID, @NonNull WiFiCipherType cipherType, @Nullable String password, @Nullable ConnectWiFiActionListener listener) {
super(SSID, listener);
this.cipherType = cipherType;
this.password = password;
}
@NonNull
@Override
public String toString() {
return super.toString() + " | " + SSID + " | " + cipherType.name();
}
}

@ -0,0 +1,26 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
import androidx.annotation.NonNull;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.RemoveWiFiActionListener;
/**
*
*/
public class WiFiRemoveAction extends IWiFiAction {
public String SSID;
public RemoveWiFiActionListener listener;
public WiFiRemoveAction(String SSID, RemoveWiFiActionListener listener) {
this.SSID = SSID;
this.listener = listener;
}
@NonNull
@Override
public String toString() {
return super.toString() + " | " + SSID;
}
}

@ -0,0 +1,16 @@
package com.yinuo.safetywatcher.watcher.wifi.info.action;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ScanWiFiActionListener;
/**
* WiFi
*/
public class WiFiScanAction extends IWiFiAction {
public ScanWiFiActionListener listener;
public WiFiScanAction(ScanWiFiActionListener listener) {
this.listener = listener;
}
}

@ -0,0 +1,13 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
import android.net.wifi.WifiConfiguration;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
public interface ConnectWiFiActionListener extends IActionListener {
void onCreateConfig(WifiConfiguration configuration);
void onResult(@Types.ConnectResultType int type);
}

@ -0,0 +1,7 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
public interface IActionListener {
void onStart();
}

@ -0,0 +1,8 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
public interface RemoveWiFiActionListener extends IActionListener {
void onResult(@Types.RemoveResultType int type);
}

@ -0,0 +1,13 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
import java.util.List;
public interface ScanWiFiActionListener extends IActionListener {
void onResult(@Types.ScanResultType int type, @Nullable List<WiFiScanInfo> list);
}

@ -0,0 +1,61 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
import android.net.wifi.WifiConfiguration;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiRemoveStatusInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectFailType;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiGetListType;
import java.util.List;
/**
* WiFi
*/
public interface WiFiListener {
/**
* WiFi
*/
void onStartScan();
/**
* WiFi
*/
void onCloseWiFi();
/**
* WiFi
*/
void onDataChange(WiFiGetListType type, List<WiFiScanInfo> list);
/**
* WiFi
*/
void onWiFiStartConnect(String SSID);
/**
* WiFi
*/
void onWiFiCreateConfig(String SSID, WifiConfiguration configuration);
/**
* WiFi
*
* @param isInit
*/
void onWiFiConnected(String SSID, boolean isInit);
/**
* WiFi
*
* @param type
*/
void onWiFiConnectFail(String SSID, WiFiConnectFailType type);
/**
* WiFi
*/
void onWiFiRemoveResult(WiFiRemoveStatusInfo info);
}

@ -0,0 +1,30 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
import android.content.Intent;
/**
* WiFi
*/
public interface WiFiStatusListener {
/**
*
*/
void handleScanResultsChanged(Intent intent);
/**
* WiFi
*/
void handleWiFiStateChanged(Intent intent);
/**
*
*/
void handleNetStateChanged(Intent intent);
/**
* WiFi()
*/
void handleSupplicantStateChanged(Intent intent);
}

@ -0,0 +1,36 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces;
import android.net.wifi.WifiInfo;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.info.action.IWiFiAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiScanAction;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
public interface WiFiSupportListener {
/**
* action
*/
@Nullable
IWiFiAction getCurrentAction();
/**
* WiFi
*/
WifiInfo getConnectedWifiInfo();
void onWiFiClose();
void onWiFiListChange();
void doneScanAction(@NonNull WiFiScanAction action);
void doneConnectSuccess(@NonNull String SSID, @Types.ConnectSuccessType int type);
void doneConnectFail(@NonNull WiFiConnectAction action);
}

@ -0,0 +1,55 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces.impl;
import android.net.wifi.WifiConfiguration;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiRemoveStatusInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiListener;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectFailType;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiGetListType;
import java.util.List;
public class WiFiListenerImpl implements WiFiListener {
@Override
public void onStartScan() {
}
@Override
public void onCloseWiFi() {
}
@Override
public void onDataChange(WiFiGetListType type, List<WiFiScanInfo> list) {
}
@Override
public void onWiFiStartConnect(String SSID) {
}
@Override
public void onWiFiCreateConfig(String SSID, WifiConfiguration configuration) {
}
@Override
public void onWiFiConnected(String SSID, boolean isInit) {
}
@Override
public void onWiFiConnectFail(String SSID, WiFiConnectFailType type) {
}
@Override
public void onWiFiRemoveResult(WiFiRemoveStatusInfo info) {
}
}

@ -0,0 +1,193 @@
package com.yinuo.safetywatcher.watcher.wifi.interfaces.impl;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import com.yinuo.safetywatcher.watcher.wifi.info.action.IWiFiAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiDirectConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiDisableAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiEnableAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiScanAction;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiStatusListener;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiSupportListener;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
import com.yinuo.safetywatcher.watcher.wifi.utils.WiFiLogUtils;
public class WiFiStatusImpl implements WiFiStatusListener {
private WiFiSupportListener mSupportListener;
public WiFiStatusImpl(WiFiSupportListener listener) {
this.mSupportListener = listener;
}
@Override
public void handleScanResultsChanged(Intent intent) {
if (null == mSupportListener) {
return;
}
IWiFiAction action = mSupportListener.getCurrentAction();
if (action instanceof WiFiScanAction) {
//扫描结束
WiFiLogUtils.d("扫描结束," + action.toString());
mSupportListener.doneScanAction((WiFiScanAction) action);
return;
}
//WiFi列表发生变动
mSupportListener.onWiFiListChange();
}
@Override
public void handleWiFiStateChanged(Intent intent) {
if (null == intent) {
return;
}
int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
switch (state) {
case WifiManager.WIFI_STATE_DISABLED: {
//WIFI处于关闭状态
WiFiLogUtils.d("WIFI已关闭");
IWiFiAction action = (null == mSupportListener) ? null : mSupportListener.getCurrentAction();
if (action instanceof WiFiDisableAction) {
action.end();
}
if (null != mSupportListener) {
mSupportListener.onWiFiClose();
}
break;
}
case WifiManager.WIFI_STATE_DISABLING: {
//正在关闭
WiFiLogUtils.d("WIFI关闭中");
break;
}
case WifiManager.WIFI_STATE_ENABLED: {
//已经打开
WiFiLogUtils.d("WIFI已打开");
//判断当前执行的action是否是WiFiScanAction
IWiFiAction action = (null == mSupportListener) ? null : mSupportListener.getCurrentAction();
if (action instanceof WiFiEnableAction) {
action.end();
}
break;
}
case WifiManager.WIFI_STATE_ENABLING: {
//正在打开
WiFiLogUtils.d("打开WIFI中...");
break;
}
default:
break;
}
}
@Override
public void handleNetStateChanged(Intent intent) {
if (null == intent) {
return;
}
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
NetworkInfo.DetailedState state = info.getDetailedState();
if (NetworkInfo.DetailedState.CONNECTED == state) {
if (null == mSupportListener) {
return;
}
WifiInfo wifiInfo = mSupportListener.getConnectedWifiInfo();
if (null == wifiInfo) {
WiFiLogUtils.d("当前连接的 WifiInfo 为空");
return;
}
String SSID = wifiInfo.getSSID();
int size = SSID.length();
SSID = SSID.substring(1, size - 1);
//连接成功
IWiFiAction action = mSupportListener.getCurrentAction();
if (action instanceof WiFiConnectAction) {
WiFiConnectAction wiFiConnectAction = (WiFiConnectAction) action;
if (!wiFiConnectAction.SSID.equals(SSID)) {
WiFiLogUtils.d("当前" + wiFiConnectAction.SSID + "与" + SSID + "不一致!");
mSupportListener.doneConnectSuccess(SSID, Types.ConnectSuccessType.NOT_MATCH);
return;
}
if (null != wiFiConnectAction.listener) {
wiFiConnectAction.listener.onResult(Types.ConnectResultType.SUCCESS);
}
mSupportListener.doneConnectSuccess(SSID, Types.ConnectSuccessType.NORMAL);
WiFiLogUtils.d("WiFi连接成功" + action.toString());
action.end();
return;
}
WiFiLogUtils.d("WiFi连接成功" + SSID);
mSupportListener.doneConnectSuccess(SSID, Types.ConnectSuccessType.SYSTEM);
}
}
@Override
public void handleSupplicantStateChanged(Intent intent) {
if (null == intent) {
return;
}
SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
int errorResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
if (null != state && state == SupplicantState.DISCONNECTED && errorResult == WifiManager.ERROR_AUTHENTICATING) {
if (null == mSupportListener) {
return;
}
//密码错误
IWiFiAction action = mSupportListener.getCurrentAction();
if (action instanceof WiFiConnectAction) {
if (Types.ActionStateType.END == action.getActionState()) {
return;
}
if (null != ((WiFiConnectAction) action).listener) {
if (action instanceof WiFiDirectConnectAction) {
((WiFiConnectAction) action).listener.onResult(Types.ConnectResultType.DIRECT_PASSWORD_ERROR);
} else {
((WiFiConnectAction) action).listener.onResult(Types.ConnectResultType.PASSWORD_ERROR);
}
}
mSupportListener.doneConnectFail(((WiFiConnectAction) action));
WiFiLogUtils.d("WiFi连接失败密码错误" + action.toString());
action.end();
}
}
}
}

@ -0,0 +1,52 @@
package com.yinuo.safetywatcher.watcher.wifi.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiStatusListener;
/**
* WiFi
*/
public class WiFiStatusReceiver extends BroadcastReceiver {
private WiFiStatusListener mCallback;
public WiFiStatusReceiver(WiFiStatusListener callback) {
this.mCallback = callback;
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (null == mCallback || null == action || TextUtils.isEmpty(action)) {
return;
}
switch (action) {
case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
mCallback.handleScanResultsChanged(intent);
break;
case WifiManager.WIFI_STATE_CHANGED_ACTION:
mCallback.handleWiFiStateChanged(intent);
break;
case WifiManager.NETWORK_STATE_CHANGED_ACTION:
mCallback.handleNetStateChanged(intent);
break;
case WifiManager.SUPPLICANT_STATE_CHANGED_ACTION:
mCallback.handleSupplicantStateChanged(intent);
break;
default:
break;
}
}
}

@ -0,0 +1,77 @@
package com.yinuo.safetywatcher.watcher.wifi.type;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class Types {
@IntDef({
ScanResultType.UNKNOWN,
ScanResultType.FREQUENTLY_SCAN_ERROR,
ScanResultType.OPEN_WIFI_ERROR,
ScanResultType.SUCCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ScanResultType {
int UNKNOWN = -1;//未知错误
int FREQUENTLY_SCAN_ERROR = 0;//频繁扫描
int OPEN_WIFI_ERROR = 1;//开启WiFi失败
int SUCCESS = 2;//扫描成功
}
@IntDef({
RemoveResultType.SYSTEM_LIMIT_ERROR,
RemoveResultType.SUCCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface RemoveResultType {
int SYSTEM_LIMIT_ERROR = 0;//系统限制,删除失败
int SUCCESS = 1;//删除成功
}
@IntDef({
ConnectResultType.UNKNOWN,
ConnectResultType.SYSTEM_LIMIT_ERROR,
ConnectResultType.TIMEOUT_ERROR,
ConnectResultType.PASSWORD_ERROR,
ConnectResultType.DIRECT_PASSWORD_ERROR,
ConnectResultType.SUCCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ConnectResultType {
int UNKNOWN = -1;//未知错误
int SYSTEM_LIMIT_ERROR = 0;//系统限制,删除失败
int TIMEOUT_ERROR = 1;//连接超时
int PASSWORD_ERROR = 2;//密码错误
int DIRECT_PASSWORD_ERROR = 3;//直连密码错误
int SUCCESS = 5;//连接成功
}
@IntDef({
ActionStateType.WAITING,
ActionStateType.PROCESS,
ActionStateType.END,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ActionStateType {
int WAITING = 0;//待执行
int PROCESS = 1;//执行中
int END = 2;//执行完成
}
@IntDef({
ConnectSuccessType.NOT_MATCH,
ConnectSuccessType.NORMAL,
ConnectSuccessType.SYSTEM,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ConnectSuccessType {
int NOT_MATCH = 1;//不匹配
int NORMAL = 2;//正常处理
int SYSTEM = 3;//没有执行操作时连接成功
}
}

@ -0,0 +1,13 @@
package com.yinuo.safetywatcher.watcher.wifi.type;
/**
* WiFi
*/
public enum WiFiCipherType {
WIFI_CIPHER_WEP,
WIFI_CIPHER_WPA,//默认都是这种
WIFI_CIPHER_NO_PASS,
WIFI_CIPHER_INVALID
}

@ -0,0 +1,10 @@
package com.yinuo.safetywatcher.watcher.wifi.type;
public enum WiFiConnectFailType {
PASSWORD_ERROR,//密码错误
DIRECT_PASSWORD_ERROR,//直接连接,密码错误
TIMEOUT_ERROR,//连接超时
SYSTEM_LIMIT_ERROR,//系统限制
UNKNOWN,//未知
}

@ -0,0 +1,20 @@
package com.yinuo.safetywatcher.watcher.wifi.type;
/**
* WiFi
*/
public enum WiFiConnectType {
DISCONNECTED(0, "未连接"),
CONNECTING(1, "连接中"),
CONNECTED(2, "已连接");
public int type;
public String state;
WiFiConnectType(int type, String state) {
this.type = type;
this.state = state;
}
}

@ -0,0 +1,11 @@
package com.yinuo.safetywatcher.watcher.wifi.type;
/**
*
*/
public enum WiFiGetListType {
TYPE_SCAN,//扫描
TYPE_SORT//排序
}

@ -0,0 +1,271 @@
package com.yinuo.safetywatcher.watcher.wifi.ui
import android.content.Context
import android.content.Intent
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiManager
import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.yinuo.safetywatcher.R
import com.yinuo.safetywatcher.databinding.ActivityMonitorBinding
import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity
import com.yinuo.safetywatcher.watcher.ui.view.ConfirmDialog
import com.yinuo.safetywatcher.watcher.wifi.WiFiModule
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiRemoveStatusInfo
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ConnectWiFiActionListener
import com.yinuo.safetywatcher.watcher.wifi.interfaces.RemoveWiFiActionListener
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ScanWiFiActionListener
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiListener
import com.yinuo.safetywatcher.watcher.wifi.interfaces.impl.WiFiListenerImpl
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiCipherType
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectFailType
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectType
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiGetListType
import com.yinuo.safetywatcher.watcher.wifi.utils.WiFiUtils
class GlobalMonitorActivity : NoOptionsActivity() {
var mData: MutableList<WiFiScanInfo>? = null
var mAdapter: WiFIAdapter? = null
private var delDialog: ConfirmDialog? = null
private var delErrorDialog: ConfirmDialog? = null
override fun initView() {
initSwitch()
initParams()
initEvents()
}
private fun initSwitch() {
val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
val wiFiEnable = WiFiUtils.isWiFiEnable(wifiManager)
mBinding.wifiSwitch.isChecked = wiFiEnable
if (wiFiEnable) {
WiFiModule.getInstance().startScan(scanActionListener)
}
mBinding.tvStatus.text = if (wiFiEnable) "WiFi已开启" else "WiFi已关闭"
mBinding.areaSwitch.setOnClickListener {
mBinding.wifiSwitch.performClick()
}
}
private fun initEvents() {
mBinding.wifiSwitch!!.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
WiFiModule.getInstance().startScan(scanActionListener)
} else {
WiFiModule.getInstance().disableWifi()
}
}
}
private fun initParams() {
mData = ArrayList()
mAdapter = WiFIAdapter(onItemClick = { wifiInfo ->
if (wifiInfo.connectType != WiFiConnectType.CONNECTED.type) {
//输入密码,连接
if (null != wifiInfo.configuration) {
WiFiModule.getInstance()
.connectWiFi(wifiInfo.configuration, getConnectActionListener(wifiInfo))
} else {
showInputDialog(wifiInfo, 0)
}
} else {
showDelDialog(wifiInfo)
}
}, onItemLongClick = { info ->
if (null != info.configuration) {
showDelDialog(info)
}
})
mBinding.rvData.adapter = mAdapter
mBinding.rvData.layoutManager = LinearLayoutManager(this@GlobalMonitorActivity)
//添加监听
WiFiModule.getInstance().addWiFiListener(TAG, mListener)
}
private val mListener: WiFiListener = object : WiFiListenerImpl() {
override fun onStartScan() {
mBinding.tvStatus!!.text = "扫描中..."
mBinding.wifiSwitch!!.isEnabled = false
}
override fun onCloseWiFi() {
mBinding.tvStatus!!.text = "WiFi已关闭"
mData!!.clear()
mAdapter?.setData(mData!!)
}
override fun onDataChange(type: WiFiGetListType, list: List<WiFiScanInfo>) {
if (type == WiFiGetListType.TYPE_SCAN) {
mBinding.wifiSwitch!!.isEnabled = true
mBinding.tvStatus!!.text = "扫描结束"
}
mData!!.clear()
mData!!.addAll(list)
mAdapter?.setData(mData!!)
}
override fun onWiFiStartConnect(SSID: String) {
mBinding.tvStatus!!.text = SSID + "连接中..."
refreshData(SSID, WiFiConnectType.CONNECTING)
}
override fun onWiFiCreateConfig(SSID: String, configuration: WifiConfiguration) {
for (info in mData!!) {
if (!TextUtils.isEmpty(SSID) && SSID == info.scanResult.SSID) {
info.configuration = configuration
break
}
}
refreshData(SSID, WiFiConnectType.CONNECTING)
}
override fun onWiFiConnected(SSID: String, isInit: Boolean) {
mBinding.tvStatus!!.text = isInit.toString() + " || " + SSID + "已连接"
refreshData(SSID, WiFiConnectType.CONNECTED)
}
override fun onWiFiConnectFail(SSID: String, type: WiFiConnectFailType) {
if (TextUtils.isEmpty(SSID)) {
return
}
mBinding.tvStatus!!.text = SSID + "连接失败," + type.name
refreshData(SSID, WiFiConnectType.DISCONNECTED)
if (type == WiFiConnectFailType.DIRECT_PASSWORD_ERROR) {
//直连密码错误,提示用户修改密码
val scanInfo = findScanInfo(SSID)
if (null != scanInfo) {
showInputDialog(scanInfo, 1)
}
}
}
override fun onWiFiRemoveResult(info: WiFiRemoveStatusInfo) {
if (!info.isSuccess) {
mBinding.tvStatus!!.text = info.SSID + "删除失败!"
showDelErrorDialog()
return
}
mBinding.tvStatus!!.text = info.SSID + "删除成功!"
for (connectInfo in mData!!) {
if (!TextUtils.isEmpty(info.SSID) && info.SSID == connectInfo.scanResult.SSID) {
connectInfo.configuration = null
break
}
}
refreshData(info.SSID, WiFiConnectType.DISCONNECTED)
}
}
private val scanActionListener: ScanWiFiActionListener?
get() = null
private fun getConnectActionListener(info: WiFiScanInfo?): ConnectWiFiActionListener? {
return null
}
private fun getRemoveActionListener(SSID: String?): RemoveWiFiActionListener? {
return null
}
/**
* 删除wifi
*/
private fun showDelDialog(info: WiFiScanInfo) {
delDialog = ConfirmDialog("确定要删除${info.scanResult.SSID}吗?删除后需要重新输入密码") {
delDialog?.dismiss()
WiFiModule.getInstance()
.removeWiFi(info.scanResult.SSID, getRemoveActionListener(info.scanResult.SSID))
}
delDialog?.show(supportFragmentManager, "del")
}
/**
* 输入密码连接wifi
*/
fun showInputDialog(info: WiFiScanInfo, type: Int) {
if (WiFiCipherType.WIFI_CIPHER_NO_PASS == info.cipherType) {
WiFiModule.getInstance()
.connectWiFi(info.scanResult.SSID, WiFiCipherType.WIFI_CIPHER_NO_PASS, null)
} else {
val dialog = InputWiFiPasswordDialog()
val bundle = Bundle()
bundle.putParcelable("info", info)
bundle.putInt("connectType", type)
dialog.arguments = bundle
dialog.show(supportFragmentManager, TAG_FRAG)
dialog.setConnectListener(getConnectActionListener(info))
}
}
/**
* 删除失败提示用户去系统设置操作
*/
fun showDelErrorDialog() {
hideInputWiFiPasswordDialog()
delErrorDialog = ConfirmDialog("由于系统限制,需要到系统设置->WiFi/WLAN中忘记网络") {
delErrorDialog?.dismiss()
val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
delErrorDialog?.show(supportFragmentManager, "error")
}
private fun hideInputWiFiPasswordDialog() {
val fragment = supportFragmentManager.findFragmentByTag(TAG_FRAG)
if (null != fragment && fragment.isVisible && fragment is InputWiFiPasswordDialog) {
fragment.dismissAllowingStateLoss()
}
}
fun findScanInfo(SSID: String): WiFiScanInfo? {
for (scanInfo in mData!!) {
if (SSID == scanInfo.scanResult.SSID) {
return scanInfo
}
}
return null
}
fun refreshData(SSID: String, connectType: WiFiConnectType) {
if (TextUtils.isEmpty(SSID)) {
return
}
for (info in mData!!) {
if (!TextUtils.isEmpty(SSID) && SSID == info.scanResult.SSID) {
info.connectType = connectType.type
} else {
info.connectType = WiFiConnectType.DISCONNECTED.type
}
}
mAdapter?.setData(mData!!)
}
override fun onDestroy() {
super.onDestroy()
WiFiModule.getInstance().removeWiFiListener(TAG)
}
override fun getTopBarTitle(): String {
return getString(R.string.wifi_setting)
}
override fun generateContentView(): View {
return mBinding.root
}
private val mBinding: ActivityMonitorBinding by lazy {
ActivityMonitorBinding.inflate(layoutInflater)
}
companion object {
const val TAG = "BaseMonitorActivity"
const val TAG_FRAG = "InputWiFiPasswordDialog"
}
}

@ -0,0 +1,123 @@
package com.yinuo.safetywatcher.watcher.wifi.ui
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.fragment.app.DialogFragment
import com.yinuo.safetywatcher.databinding.DialogInputWifiPasswordBinding
import com.yinuo.safetywatcher.watcher.utils.hideIme
import com.yinuo.safetywatcher.watcher.utils.showIme
import com.yinuo.safetywatcher.watcher.wifi.WiFiModule
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo
import com.yinuo.safetywatcher.watcher.wifi.interfaces.ConnectWiFiActionListener
/**
* wifi密码输入框
*/
class InputWiFiPasswordDialog : DialogFragment() {
private var mInfo: WiFiScanInfo? = null
private var mConnectType = 0
private var mBinding: DialogInputWifiPasswordBinding? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
mBinding = DialogInputWifiPasswordBinding.inflate(inflater, container, false)
return mBinding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val bundle = arguments
if (null != bundle) {
mInfo = bundle.getParcelable("info")
mConnectType = bundle.getInt("connectType", 0)
}
if (null == mInfo) {
dismissAllowingStateLoss()
return
}
if (mConnectType == 1) {
mBinding?.tvTitle?.text = "修改" + mInfo!!.scanResult.SSID
} else {
mBinding?.tvTitle?.text = mInfo!!.scanResult.SSID
}
setListener()
}
private fun setListener() {
mBinding?.etPassword?.setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
if (event.action == KeyEvent.ACTION_DOWN) {
mBinding?.tvCancel?.requestFocus()
}
return@setOnKeyListener true
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
if (event.action == KeyEvent.ACTION_DOWN) {
mBinding?.etPassword?.showIme()
}
return@setOnKeyListener true
}
return@setOnKeyListener false
}
mBinding?.etPassword?.setOnFocusChangeListener { v, hasFocus ->
if (!hasFocus) {
mBinding?.etPassword?.hideIme()
} else {
mBinding?.etPassword?.showIme()
}
}
mBinding?.tvCancel?.setOnClickListener {
dismissAllowingStateLoss()
}
mBinding?.tvConnect?.setOnClickListener {
val trimPass = mBinding?.etPassword?.text.toString().trim { it <= ' ' }
//连接
if (TextUtils.isEmpty(trimPass)) {
return@setOnClickListener
}
WiFiModule.getInstance().connectWiFi(
mInfo!!.scanResult.SSID,
mInfo!!.cipherType,
trimPass,
mConnectActionListener
)
dismissAllowingStateLoss()
}
}
override fun onStart() {
super.onStart()
val dialog = dialog
dialog?.setCanceledOnTouchOutside(true)
val window = dialog?.window
if (null != window) {
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val lp = window.attributes
lp.gravity = Gravity.CENTER
lp.width = 480
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
window.attributes = lp
}
}
private var mConnectActionListener: ConnectWiFiActionListener? = null
fun setConnectListener(actionListener: ConnectWiFiActionListener?) {
mConnectActionListener = actionListener
}
}

@ -0,0 +1,84 @@
package com.yinuo.safetywatcher.watcher.wifi.ui
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.yinuo.safetywatcher.R
import com.yinuo.safetywatcher.databinding.ItemNetworkConfigBinding
import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiCipherType
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectType
class WiFIAdapter(
private val onItemClick: ((WiFiScanInfo) -> Unit)? = null,
private val onItemLongClick: ((WiFiScanInfo) -> Unit)? = null
) :
BaseRvAdapter<WiFiScanInfo, ItemNetworkConfigBinding, WiFIAdapter.WiFiViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WiFiViewHolder {
return WiFiViewHolder(
ItemNetworkConfigBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
), onItemClick, onItemLongClick
);
}
class WiFiViewHolder(
private val binding: ItemNetworkConfigBinding,
private val onItemClick: ((WiFiScanInfo) -> Unit)?,
private val onItemLongClick: ((WiFiScanInfo) -> Unit)?
) :
BaseViewHolder<WiFiScanInfo, ItemNetworkConfigBinding>(binding) {
override fun bindView(info: WiFiScanInfo) {
val context = binding.root.context
binding.root.setOnClickListener {
onItemClick?.invoke(info)
}
binding.root.setOnLongClickListener {
onItemLongClick?.invoke(info)
return@setOnLongClickListener true
}
if (null != info.configuration) {
if (info.connectType == WiFiConnectType.CONNECTED.type) {
binding.tvNetName.text = info.scanResult.SSID
} else {
binding.tvNetName.text = info.scanResult.SSID + "(已保存)"
}
} else {
binding.tvNetName.text = info.scanResult.SSID
}
val noPass = WiFiCipherType.WIFI_CIPHER_NO_PASS == info.cipherType
if (noPass) {
binding.ivStatusLock.visibility = View.GONE
} else {
binding.ivStatusLock.visibility = View.VISIBLE
}
binding.ivStatusLock.setColorFilter(Color.WHITE)
if (info.connectType == WiFiConnectType.CONNECTED.type) {
binding.ivStatusConnect.visibility = View.VISIBLE
binding.progressBar.visibility = View.GONE
} else if (info.connectType == WiFiConnectType.CONNECTING.type) {
//连接中
binding.ivStatusConnect.visibility = View.GONE
binding.progressBar.visibility = View.VISIBLE
} else {
binding.ivStatusConnect.visibility = View.GONE
binding.progressBar.visibility = View.GONE
}
when (info.level) {
1 -> binding.ivStatusWifi.setImageResource(R.drawable.wifi_1)
2 -> binding.ivStatusWifi.setImageResource(R.drawable.wifi_2)
else -> binding.ivStatusWifi.setImageResource(R.drawable.wifi_3)
}
}
}
}

@ -0,0 +1,32 @@
package com.yinuo.safetywatcher.watcher.wifi.utils;
import android.util.Log;
public final class WiFiLogUtils {
private static final String TAG = "WiFiTool-log";
private static int log_level = 0;
/**
*
*
* @param level
*/
public static void setLogLevel(int level) {
log_level = level;
}
public static void d(String msg) {
if (log_level < 2) {
Log.d(TAG, msg);
}
}
public static void e(Throwable throwable) {
if (log_level < 7) {
Log.e(TAG, "", throwable);
}
}
}

@ -0,0 +1,574 @@
package com.yinuo.safetywatcher.watcher.wifi.utils;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiCreateConfigStatusInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiRemoveStatusInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.action.IWiFiAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiDirectConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiDisableAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiEnableAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiNormalConnectAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiRemoveAction;
import com.yinuo.safetywatcher.watcher.wifi.info.action.WiFiScanAction;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiListener;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.WiFiSupportListener;
import com.yinuo.safetywatcher.watcher.wifi.interfaces.impl.WiFiStatusImpl;
import com.yinuo.safetywatcher.watcher.wifi.receiver.WiFiStatusReceiver;
import com.yinuo.safetywatcher.watcher.wifi.type.Types;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectFailType;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiGetListType;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* WiFiAction
*/
public class WiFiModuleService {
private WeakReference<Context> mContext;
private WifiManager mWifiManager;
private final List<IWiFiAction> actionList = Collections.synchronizedList(new ArrayList<>());
private final HashMap<String, WiFiListener> mListeners = new HashMap<>();//存放WiFi状态监听回调
private boolean stopFlag = false;
private Handler mHandler;
private WiFiStatusReceiver mStatusReceiver;
private WiFiStatusImpl mWiFiStatusImpl;
public WiFiModuleService(Context context) {
this.mContext = new WeakReference<>(context);
this.mWifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
this.mHandler = new Handler(Looper.getMainLooper());
this.mWiFiStatusImpl = new WiFiStatusImpl(getWiFiSupportListener());
registerReceiver();
new WorkThread(mHandler).start();
}
/**
* 广
*/
private void registerReceiver() {
try {
this.mStatusReceiver = new WiFiStatusReceiver(mWiFiStatusImpl);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);//监听wifi列表变化开启一个热点或者关闭一个热点
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);//监听wifi是开关变化的状态
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);//监听wifi连接状态广播,是否连接了一个有效路由
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);//监听wifi连接失败
this.mContext.get().registerReceiver(this.mStatusReceiver, intentFilter);
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
/**
* 广
*/
private void unregisterReceiver() {
try {
if (null != this.mContext.get()) {
this.mContext.get().unregisterReceiver(this.mStatusReceiver);
}
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
/**
*
*/
public void addAction(IWiFiAction action) {
synchronized (actionList) {
boolean absent = !actionList.contains(action);
if (absent) {
actionList.add(action);
WiFiLogUtils.d("已加入待执行队列中," + action.toString());
}
}
}
/**
* WiFi
*
* @param key
* @param listener
*/
public void addWiFiListener(String key, WiFiListener listener) {
try {
if (mListeners.containsKey(key)) {
return;
}
mListeners.put(key, listener);
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
/**
* WiFi
*
* @param key
*/
public void removeWiFiListener(String key) {
try {
if (!mListeners.containsKey(key)) {
return;
}
mListeners.remove(key);
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
private WiFiSupportListener getWiFiSupportListener() {
return new WiFiSupportListener() {
@Nullable
@Override
public IWiFiAction getCurrentAction() {
synchronized (actionList) {
for (IWiFiAction action : actionList) {
if (Types.ActionStateType.PROCESS == action.getActionState()) {
return action;
}
}
return null;
}
}
@Override
public WifiInfo getConnectedWifiInfo() {
return WiFiUtils.getConnectedWifiInfo(mWifiManager);
}
@Override
public void onWiFiClose() {
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onCloseWiFi();
}
}
@Override
public void onWiFiListChange() {
//TODO 在子线程查询
List<WiFiScanInfo> list = WiFiUtils.getScanList(mWifiManager);
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onDataChange(WiFiGetListType.TYPE_SORT, list);
}
}
@Override
public void doneScanAction(@NonNull WiFiScanAction action) {
//TODO 在子线程查询
List<WiFiScanInfo> list = WiFiUtils.getScanList(mWifiManager);
if (null != action.listener) {
action.listener.onResult(Types.ScanResultType.SUCCESS, list);
}
action.end();
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onDataChange(WiFiGetListType.TYPE_SCAN, list);
}
}
@Override
public void doneConnectSuccess(@NonNull String SSID, int type) {
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnected(SSID, Types.ConnectSuccessType.SYSTEM == type);
}
}
@Override
public void doneConnectFail(@NonNull WiFiConnectAction action) {
if (action instanceof WiFiDirectConnectAction) {
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnectFail(action.SSID, WiFiConnectFailType.DIRECT_PASSWORD_ERROR);
}
return;
}
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnectFail(action.SSID, WiFiConnectFailType.PASSWORD_ERROR);
}
}
};
}
private class WorkThread extends Thread {
Handler mHandler;
WorkThread(Handler handler) {
this.mHandler = handler;
}
@Override
public void run() {
super.run();
while (!stopFlag) {
synchronized (actionList) {
if (actionList.isEmpty()) {
continue;
}
//始终获取第一个操作
IWiFiAction action = actionList.get(0);
if (Types.ActionStateType.WAITING == action.getActionState()) {
dispatchAction(action, mHandler);
continue;
}
if (Types.ActionStateType.END == action.getActionState()) {
actionList.remove(action);
WiFiLogUtils.d("执行完毕,移除," + action.toString());
}
}
}
}
}
/**
* WiFi
*/
private void dispatchAction(IWiFiAction action, Handler handler) {
// 检测WiFi是否开启
boolean isWiFiEnable = WiFiUtils.isWiFiEnable(mWifiManager);
if (action instanceof WiFiDisableAction) {
action.setState(Types.ActionStateType.PROCESS);
WiFiLogUtils.d("开始执行," + action.toString());
if (!isWiFiEnable) {
//不可用
action.end();
return;
}
//禁用WiFi
WiFiUtils.setWifiEnabled(mWifiManager, false);
return;
}
if (action instanceof WiFiEnableAction) {
action.setState(Types.ActionStateType.PROCESS);
WiFiLogUtils.d("开始执行," + action.toString());
if (isWiFiEnable) {
//可用
action.end();
return;
}
//启用WiFi
WiFiUtils.setWifiEnabled(mWifiManager, true);
return;
}
if (!isWiFiEnable) {
//插入打开WiFi事件阻塞后续WiFi操作
insertOpenWiFiAction();
return;
}
action.setState(Types.ActionStateType.PROCESS);
WiFiLogUtils.d("开始执行," + action.toString());
if (action instanceof WiFiScanAction) {
handleWiFiScanAction((WiFiScanAction) action, handler);
} else if (action instanceof WiFiNormalConnectAction) {
handleWiFiNormalConnectAction((WiFiNormalConnectAction) action, handler);
} else if (action instanceof WiFiDirectConnectAction) {
handleWiFiDirectConnectAction((WiFiDirectConnectAction) action, handler);
} else if (action instanceof WiFiRemoveAction) {
handleWiFiRemoveAction((WiFiRemoveAction) action, handler);
} else {
WiFiLogUtils.d("不支持此操作," + action.toString());
action.end();
}
}
/**
* WiFi
*/
private void insertOpenWiFiAction() {
synchronized (actionList) {
WiFiEnableAction openAction = new WiFiEnableAction();
if (actionList.isEmpty()) {
actionList.add(0, openAction);
return;
}
IWiFiAction action = actionList.get(0);
if (action instanceof WiFiEnableAction) {
return;
}
actionList.add(0, openAction);
}
}
private void handleWiFiScanAction(final WiFiScanAction action, Handler handler) {
handler.post(() -> {
if (null != action.listener) {
action.listener.onStart();
}
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onStartScan();
}
});
boolean success = WiFiUtils.startScan(mWifiManager);
if (!success) {
final List<WiFiScanInfo> list = WiFiUtils.getScanList(mWifiManager);
handler.post(() -> {
if (null != action.listener) {
action.listener.onResult(Types.ScanResultType.FREQUENTLY_SCAN_ERROR, list);
}
action.end();
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onDataChange(WiFiGetListType.TYPE_SCAN, list);
}
});
}
}
private void handleWiFiNormalConnectAction(final WiFiNormalConnectAction action, Handler handler) {
handler.post(() -> {
if (null != action.listener) {
action.listener.onStart();
}
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiStartConnect(action.SSID);
}
});
startDelayCheck(action);
final WiFiCreateConfigStatusInfo statusInfo = WiFiUtils.connectWiFi(mWifiManager, action.SSID,
action.cipherType, action.password, mContext.get());
if (!statusInfo.isSuccess()) {
handler.post(() -> {
WiFiLogUtils.d("配置创建失败," + action.toString());
if (null != action.listener) {
action.listener.onResult(Types.ConnectResultType.SYSTEM_LIMIT_ERROR);
}
action.end();
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnectFail(action.SSID, WiFiConnectFailType.SYSTEM_LIMIT_ERROR);
}
});
return;
}
//配置创建成功
handler.post(() -> {
WiFiLogUtils.d("配置创建成功," + action.toString());
if (null != action.listener) {
action.listener.onCreateConfig(statusInfo.configuration);
}
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiCreateConfig(action.SSID, statusInfo.configuration);
}
//连接WiFi
boolean success = WiFiUtils.enableNetwork(mWifiManager, statusInfo.configuration.networkId);
if (!success) {
//连接失败
WiFiLogUtils.d("连接WiFi失败" + action.toString());
if (null != action.listener) {
action.listener.onResult(Types.ConnectResultType.UNKNOWN);
}
action.end();
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnectFail(action.SSID, WiFiConnectFailType.UNKNOWN);
}
}
});
}
private void handleWiFiDirectConnectAction(final WiFiDirectConnectAction action, Handler handler) {
handler.post(new Runnable() {
@Override
public void run() {
if (null != action.listener) {
action.listener.onStart();
}
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiStartConnect(action.SSID);
}
}
});
startDelayCheck(action);
WiFiUtils.closeAllConnect(mWifiManager);
boolean success = WiFiUtils.enableNetwork(mWifiManager, action.configuration.networkId);
if (!success) {
//连接失败
handler.post(new Runnable() {
@Override
public void run() {
WiFiLogUtils.d("直连WiFi失败" + action.toString());
if (null != action.listener) {
action.listener.onResult(Types.ConnectResultType.UNKNOWN);
}
action.end();
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnectFail(action.SSID, WiFiConnectFailType.UNKNOWN);
}
}
});
}
}
private void handleWiFiRemoveAction(final WiFiRemoveAction action, Handler handler) {
handler.post(() -> {
if (null != action.listener) {
action.listener.onStart();
}
});
final WiFiRemoveStatusInfo statusInfo = WiFiUtils.removeWiFi(mWifiManager, action.SSID, mContext.get());
handler.post(() -> {
WiFiLogUtils.d("删除WiFi " + statusInfo.isSuccess + " | " + action.toString());
if (null != action.listener) {
if (statusInfo.isSuccess) {
action.listener.onResult(Types.RemoveResultType.SUCCESS);
} else {
action.listener.onResult(Types.RemoveResultType.SYSTEM_LIMIT_ERROR);
}
}
action.end();
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiRemoveResult(statusInfo);
}
});
}
/**
*
*/
private void startDelayCheck(final WiFiConnectAction action) {
if (action.timeout <= 1000 * 3) {
WiFiLogUtils.d("超时时间设置小于3秒不予超时检测" + action.toString());
return;
}
action.startDelayCheck(mHandler, () -> {
if (Types.ActionStateType.END == action.getActionState()) {
WiFiLogUtils.d("已经结束掉了忽略连接WiFi超时" + action.toString());
return;
}
WiFiLogUtils.d("连接WiFi超时" + action.toString());
WiFiUtils.closeAllConnect(mWifiManager);
if (null != action.listener) {
action.listener.onResult(Types.ConnectResultType.TIMEOUT_ERROR);
}
action.end();
// 回调全局监听
for (Map.Entry<String, WiFiListener> entry : mListeners.entrySet()) {
entry.getValue().onWiFiConnectFail(action.SSID, WiFiConnectFailType.TIMEOUT_ERROR);
}
});
}
/**
*
*/
public void destroy() {
try {
stopFlag = true;
unregisterReceiver();
mHandler.removeCallbacksAndMessages(null);
synchronized (actionList) {
actionList.clear();
}
mWifiManager = null;
WiFiLogUtils.d("销毁资源结束");
} catch (Exception e) {
WiFiLogUtils.e(e);
}
}
}

@ -0,0 +1,456 @@
package com.yinuo.safetywatcher.watcher.wifi.utils;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.text.TextUtils;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiCreateConfigStatusInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiRemoveStatusInfo;
import com.yinuo.safetywatcher.watcher.wifi.info.WiFiScanInfo;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiCipherType;
import com.yinuo.safetywatcher.watcher.wifi.type.WiFiConnectType;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* WiFi
*/
public final class WiFiUtils {
/**
* WiFi
*
* @return
*/
public static boolean isWiFiEnable(WifiManager manager) {
try {
if (null == manager) {
return false;
}
return manager.isWifiEnabled();
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return false;
}
/**
*
*
* @return
*/
public static boolean startScan(WifiManager manager) {
try {
if (null == manager) {
return false;
}
return manager.startScan();
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return false;
}
/**
* WiFi
*
* @return
*/
public static boolean setWifiEnabled(WifiManager manager, boolean isOpen) {
try {
if (null == manager) {
return false;
}
return manager.setWifiEnabled(isOpen);
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return false;
}
/**
* WiFi
*/
public static List<WiFiScanInfo> getScanList(WifiManager manager) {
if (null == manager) {
return new ArrayList<>();
}
String curSSID = isActiveWifi(manager) ? manager.getConnectionInfo().getSSID() : "";
List<ScanResult> results = noSameName(manager.getScanResults());
List<WiFiScanInfo> list = new ArrayList<>();
boolean isCur;
WiFiScanInfo curInfo = null;//当前连接上的wifi
List<WiFiScanInfo> normalList = new ArrayList<>();//不存在配置的列表
List<WiFiScanInfo> existConfigList = new ArrayList<>();//存在配置的列表
for (ScanResult result : results) {
WiFiScanInfo connectInfo = new WiFiScanInfo();
connectInfo.scanResult = result;
connectInfo.configuration = getExistConfig(manager, result.SSID);
isCur = (!TextUtils.isEmpty(curSSID) && curSSID.equals("\"" + result.SSID + "\""));
connectInfo.connectType = (isCur ? WiFiConnectType.CONNECTED.type : WiFiConnectType.DISCONNECTED.type);
connectInfo.level = WifiManager.calculateSignalLevel(result.level, 4) + 1;
if (isCur) {
//当前已连接
curInfo = connectInfo;
} else {
if (null != connectInfo.configuration) {
//存在配置
existConfigList.add(connectInfo);
} else {
normalList.add(connectInfo);
}
}
}
//优先把保存了配置的放在上面
if (null != curInfo) {
list.add(curInfo);
}
Collections.sort(existConfigList);
list.addAll(existConfigList);
Collections.sort(normalList);
list.addAll(normalList);
return list;
}
/**
* WiFi
*/
public static WifiInfo getConnectedWifiInfo(WifiManager manager) {
boolean isActive = isActiveWifi(manager);
if (isActive) {
return manager.getConnectionInfo();
}
return null;
}
/**
* WiFi
*/
public static boolean isActiveWifi(WifiManager manager) {
if (null == manager) {
return false;
}
WifiInfo info = manager.getConnectionInfo();
if (null == info) {
return false;
}
String ssid = info.getSSID();
return SupplicantState.COMPLETED == info.getSupplicantState()
&& !TextUtils.isEmpty(ssid)
&& !ssid.equalsIgnoreCase("0x")
&& !"<unknown ssid>".equals(ssid);
}
/**
*
*/
public static void closeAllConnect(WifiManager manager) {
if (null == manager) {
return;
}
// FIXME: 2019/4/16 防止自动连接,小米等手机会弹出权限框
for (WifiConfiguration c : manager.getConfiguredNetworks()) {
manager.disableNetwork(c.networkId);
}
// 断开后会自动连接WiFi
// manager.disconnect();
}
/**
* WiFi
*/
public static WiFiCreateConfigStatusInfo connectWiFi(WifiManager manager, String SSID, WiFiCipherType type, String pwd, Context context) {
WiFiCreateConfigStatusInfo info = new WiFiCreateConfigStatusInfo();
info.SSID = SSID;
info.isSuccess = false;
//先关闭当前所有已连接的网络
closeAllConnect(manager);
WifiConfiguration config = getExistConfig(manager, SSID);
if (null == config) {
//不存在旧的配置添加WiFi
return addWifi(manager, SSID, type, pwd);
}
//存在旧的配置先尝试移除WiFi
if (removeWiFi(manager, SSID, context).isSuccess) {
//移除成功重新添加WiFi
return addWifi(manager, SSID, type, pwd);
}
return info;
}
/**
* networkIdWiFi
*/
public static boolean enableNetwork(WifiManager manager, int networkId) {
return null != manager && manager.enableNetwork(networkId, true);
}
/**
* WiFi
* <p>Android6.0 WIFI</p>
*/
public static WiFiRemoveStatusInfo removeWiFi(WifiManager manager, String SSID, Context context) {
WiFiRemoveStatusInfo info = new WiFiRemoveStatusInfo();
info.SSID = SSID;
if (null == manager) {
return info;
}
WifiConfiguration config = getExistConfig(manager, SSID);
if (null == config) {
//如果不存在配置,默认是删除成功
info.isSuccess = true;
return info;
}
if (config.networkId == -1) {
info.isSuccess = false;
WiFiLogUtils.d("networkId 非法!");
return info;
}
boolean isSystemApp = isSystemApplication(context);
if (isSystemApp) {
WiFiLogUtils.d("是系统App可以直接删除");
info.isSuccess = manager.disableNetwork(config.networkId)
&& manager.removeNetwork(config.networkId)
&& manager.saveConfiguration();
return info;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//6.0之前
info.isSuccess = manager.disableNetwork(config.networkId)
&& manager.removeNetwork(config.networkId)
&& manager.saveConfiguration();
return info;
}
try {
//获取当前WiFi的创建者
Field field = config.getClass().getDeclaredField("creatorName");
field.setAccessible(true);
Object creatorName = field.get(config);
WiFiLogUtils.d("field:" + field + "||creatorName" + creatorName);
if (context.getPackageName().equals(creatorName)) {
WiFiLogUtils.d("是当前app创建的WiFi可以直接删除");
info.isSuccess = manager.disableNetwork(config.networkId)
&& manager.removeNetwork(config.networkId)
&& manager.saveConfiguration();
}
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return info;
}
/**
* WiFi
*/
private static WiFiCreateConfigStatusInfo addWifi(WifiManager manager, String SSID, WiFiCipherType type, String pwd) {
WiFiCreateConfigStatusInfo configInfo = new WiFiCreateConfigStatusInfo();
configInfo.SSID = SSID;
try {
WifiConfiguration configuration = createConfiguration(SSID, type, pwd);
configuration.networkId = manager.addNetwork(configuration);
configInfo.configuration = configuration;
configInfo.isSuccess = (configuration.networkId != -1);
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return configInfo;
}
/**
*
*/
private static WifiConfiguration createConfiguration(String SSID, WiFiCipherType type, String password) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
switch (type) {
case WIFI_CIPHER_NO_PASS:
// config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
// config.wepTxKeyIndex = 0;
break;
case WIFI_CIPHER_WEP:
if (!TextUtils.isEmpty(password)) {
if (isHexWepKey(password)) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = "\"" + password + "\"";
}
}
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
break;
case WIFI_CIPHER_WPA:
config.preSharedKey = "\"" + password + "\"";
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.status = WifiConfiguration.Status.ENABLED;
default:
break;
}
return config;
}
/**
*
*/
private static WifiConfiguration getExistConfig(WifiManager manager, String SSID) {
if (null == manager) {
return null;
}
try {
List<WifiConfiguration> existingConfigs = manager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
return existingConfig;
}
}
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return null;
}
/**
* WIFI
*/
private static List<ScanResult> noSameName(List<ScanResult> oldSr) {
List<ScanResult> newSr = new ArrayList<>();
for (ScanResult result : oldSr) {
if (!TextUtils.isEmpty(result.SSID) && !containName(newSr, result.SSID)) {
newSr.add(result);
}
}
return newSr;
}
/**
* WIFI
*/
private static boolean containName(List<ScanResult> sr, String name) {
for (ScanResult result : sr) {
if (!TextUtils.isEmpty(result.SSID) && result.SSID.equals(name)) {
return true;
}
}
return false;
}
private static boolean isHexWepKey(String wepKey) {
final int len = wepKey.length();
// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
return (len == 10 || len == 26 || len == 58) && isHex(wepKey);
}
private static boolean isHex(String key) {
for (int i = key.length() - 1; i >= 0; i--) {
final char c = key.charAt(i);
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a'
&& c <= 'f')) {
return false;
}
}
return true;
}
private static boolean isSystemApplication(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
ApplicationInfo app = packageManager.getApplicationInfo(context.getPackageName(), 0);
return (app != null && (app.flags & ApplicationInfo.FLAG_SYSTEM) > 0);
} catch (Exception e) {
WiFiLogUtils.e(e);
}
return false;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/colorTxt" />
<size android:width="2dp" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#F4F4F4" />
<corners android:radius="8dp" />
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:drawable="@drawable/ic_progress"
android:fromDegrees="0.0"
android:pivotX="50.0%"
android:pivotY="50.0%"
android:toDegrees="360.0" />
</item>
</layer-list>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/area_switch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:gravity="center_vertical"
android:paddingStart="@dimen/_61dp"
android:paddingEnd="@dimen/_61dp">
<TextView
android:id="@+id/tv_status"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginVertical="20dp"
android:textColor="@color/white"
android:textSize="@dimen/_36dp" />
<Switch
android:id="@+id/wifi_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/wifi_switch" />
</LinearLayout>

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/_480dp"
android:layout_height="wrap_content"
android:background="@drawable/warn_setting_btn_bg">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@color/white"
android:textSize="@dimen/_38dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="BLACK-1" />
<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="密码"
android:textColor="@color/colorTxtGray"
android:textSize="@dimen/_23dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<EditText
android:id="@+id/et_password"
android:layout_width="0dp"
android:layout_height="@dimen/_68dp"
android:layout_margin="12dp"
android:background="@drawable/bg_input"
android:inputType="textPassword"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textCursorDrawable="@drawable/bg_cursor"
android:textSize="@dimen/font_24dp"
android:focusable="true"
android:focusedByDefault="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_password" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="@dimen/_81dp"
android:background="@drawable/cancel_btn_bg"
android:layout_marginTop="@dimen/_12dp"
android:focusable="true"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/white_30"
android:textSize="@dimen/_36dp"
android:nextFocusRight="@id/tv_connect"
app:layout_constraintEnd_toEndOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_password" />
<TextView
android:id="@+id/tv_connect"
android:layout_width="0dp"
android:layout_height="@dimen/_81dp"
android:background="@drawable/confirm_btn_bg_red"
android:focusable="true"
android:gravity="center"
android:text="@string/confirm"
android:textColor="@color/white"
android:textSize="@dimen/_36dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="@+id/tv_cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="@dimen/_108dp"
android:paddingStart="@dimen/_121dp"
android:paddingEnd="@dimen/_61dp"
android:focusable="true"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_status_connect"
android:layout_width="@dimen/_32dp"
android:layout_height="@dimen/_32dp"
android:src="@drawable/ic_select_s"
android:visibility="gone"
tools:visibility="visible" />
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="@dimen/_32dp"
android:layout_height="@dimen/_32dp"
android:indeterminate="false"
android:indeterminateDrawable="@drawable/loading_img"
android:visibility="gone"/>
<TextView
android:id="@+id/tv_net_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="@dimen/_12dp"
android:textColor="@color/white"
android:textSize="@dimen/_36dp"
tools:text="BLACK1" />
<ImageView
android:id="@+id/iv_status_wifi"
android:layout_width="@dimen/_32dp"
android:layout_height="@dimen/_32dp"
android:layout_marginLeft="@dimen/_12dp"
app:tint="@color/white"
android:src="@drawable/wifi_3" />
<ImageView
android:id="@+id/iv_status_lock"
android:layout_width="@dimen/_32dp"
android:layout_height="@dimen/_32dp"
android:layout_marginLeft="@dimen/_12dp"
app:tint="@color/white"
android:src="@drawable/ic_password" />
</LinearLayout>

@ -11,6 +11,7 @@
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_marginTop="@dimen/_36dp"
android:paddingHorizontal="@dimen/_12dp"
android:layout_weight="1"
android:gravity="center"
android:text="@string/sync_data_tip"

@ -23,4 +23,7 @@
<color name="color_ok">#01E41C</color>
<color name="color_offline">#999999</color>
<color name="color_error">#E40101</color>
<color name="colorTxt">#191F25</color>
<color name="colorTxtGray">#BFBFBF</color>
</resources>

Loading…
Cancel
Save