index.uts 21.9 KB
Newer Older
1
import Context from "android.content.Context";
2
import { UTSAndroid } from "io.dcloud.uts";
3
import WifiManager from "android.net.wifi.WifiManager";
杜庆泉's avatar
杜庆泉 已提交
4
import WifiInfo from "android.net.wifi.WifiInfo";
杜庆泉's avatar
杜庆泉 已提交
5 6 7 8 9 10 11 12
import Manifest from "android.Manifest";
import PackageManager from "android.content.pm.PackageManager";
import ScanResult from "android.net.wifi.ScanResult";
import BroadcastReceiver from "android.content.BroadcastReceiver";
import ActivityCompat from "androidx.core.app.ActivityCompat";
import IntentFilter from "android.content.IntentFilter";
import JSONObject from "com.alibaba.fastjson.JSONObject";
import Intent from "android.content.Intent";
杜庆泉's avatar
杜庆泉 已提交
13
import Thread from "java.lang.Thread";
14

杜庆泉's avatar
杜庆泉 已提交
15
import WifiConfiguration from 'android.net.wifi.WifiConfiguration';
16 17 18
import AuthAlgorithm from 'android.net.wifi.WifiConfiguration.AuthAlgorithm';
import KeyMgmt from 'android.net.wifi.WifiConfiguration.KeyMgmt';
import TextUtils from 'android.text.TextUtils';
19

杜庆泉's avatar
杜庆泉 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
import { UniWifiResult, GetConnectedWifiOptions, WifiConnectOption, WifiOption, UniWifiInfo,UniWifiPartialInfo, UniWifiCallback, StartWifi, StopWifi, GetWifiList, GetConnectedWifi, OnGetWifiList, OnWifiConnectedWithPartialInfo, OnOffWifiConnectedWithPartialInfo, OnWifiConnected, ConnectWifi, OffGetWifiList, OffWifiConnected, SetWifiList } from "../interface.uts"



// /**
//  * Wifi 函数通用入参封装
//  */
// type WifiOption = {
// 	success?: (res: object) => void;
// 	fail?: (res: object) => void;
// 	complete?: (res: object) => void;
// };


// /**
//  * 获取当前链接的wifi信息
//  */
// type GetConnectedWifiOptions = {
// 	partialInfo?: boolean
// 	success?: (res: UTSJSONObject) => void
// 	fail?: (res: UTSJSONObject) => void
// 	complete?: (res: UTSJSONObject) => void
// }

// /**
//  * Wifi 链接参数封装
//  */
// type WifiConnectOption = {
// 	SSID:string;
// 	BSSID?:string;
// 	password:string;
// 	maunal:boolean;
// 	// 只返回ssid
// 	partialInfo:boolean;
// 	success?: (res: object) => void;
// 	fail?: (res: object) => void;
// 	complete?: (res: object) => void;
// }
杜庆泉's avatar
杜庆泉 已提交
58

杜庆泉's avatar
杜庆泉 已提交
59 60 61


/**
杜庆泉's avatar
杜庆泉 已提交
62 63
	* 全局数据储存
	*/
杜庆泉's avatar
杜庆泉 已提交
64
class Global {
杜庆泉's avatar
杜庆泉 已提交
65 66 67
	static mReceiver : CustomBroadcastReceiver | null = null;
	static WIFI_AUTH_OPEN : string = "";
	static WIFI_AUTH_ROAM : String = "[ESS]";
杜庆泉's avatar
杜庆泉 已提交
68
	// 扫描wifi结果
杜庆泉's avatar
杜庆泉 已提交
69
	static scanList : AndroidUniWifiInfo[] = []
杜庆泉's avatar
杜庆泉 已提交
70
	// 获取wifi列表监听
杜庆泉's avatar
杜庆泉 已提交
71
	static getWifiListCallbackList : UTSCallback[] = []
杜庆泉's avatar
杜庆泉 已提交
72
	// wifi链接监听
杜庆泉's avatar
杜庆泉 已提交
73 74
	static onWifiConnectCallbackList : UTSCallback[] = []
	static onWifiConnectWithPartialInfoCallbackList : UTSCallback[] = []
杜庆泉's avatar
杜庆泉 已提交
75 76 77
}


78
/**
杜庆泉's avatar
杜庆泉 已提交
79 80 81
	* 是否是标准的16进制字符
	*/
function isHex(key : string) : boolean {
82 83 84
	for (var i = key.length - 1; i >= 0; i--) {
		let c = key.charAt(i);
		if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a'
杜庆泉's avatar
杜庆泉 已提交
85
			&& c <= 'f')) {
86 87 88 89 90 91 92 93
			return false;
		}
	}

	return true;
}

/**
杜庆泉's avatar
杜庆泉 已提交
94 95 96
	* 判断是否是wep格式的key
	*/
function isHexWepKey(wepKey : string) : boolean {
97 98 99 100 101 102 103 104 105 106
	let len = wepKey.length;

	// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
	if (len != 10 && len != 26 && len != 58) {
		return false;
	}

	return isHex(wepKey);
}

杜庆泉's avatar
杜庆泉 已提交
107 108 109 110 111 112 113 114
export type AndroidUniWifiInfo = {
	SSID : string;
	BSSID ?: string;
	secure : boolean;
	signalStrength : number;
	frequency : number;
	securityType : string;
}
杜庆泉's avatar
杜庆泉 已提交
115

杜庆泉's avatar
杜庆泉 已提交
116 117 118 119 120 121 122
function wrapUniWifiInfoFromAndroid(androidInfo:AndroidUniWifiInfo): UniWifiInfo{
	let ret : UniWifiInfo = {
		SSID: androidInfo.SSID,
		BSSID: androidInfo.BSSID,
		secure: androidInfo.secure,
		signalStrength: androidInfo.signalStrength,
		frequency: androidInfo.frequency,
杜庆泉's avatar
杜庆泉 已提交
123
	}
杜庆泉's avatar
杜庆泉 已提交
124 125
	return ret
}
杜庆泉's avatar
杜庆泉 已提交
126

杜庆泉's avatar
杜庆泉 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
function wrapUniWifiInfoFromScan(scanResult : ScanResult) : AndroidUniWifiInfo {

	let ret : AndroidUniWifiInfo = {
		SSID: "",
		secure: false,
		signalStrength: 0,
		frequency: 0,
		securityType:"NONE"
	}
	if (scanResult != null) {
		// 如果是通过扫描列表得到的数据,进行封装
		ret.BSSID = scanResult.BSSID;
		ret.SSID = scanResult.SSID;

		ret.signalStrength = scanResult.level;
		ret.frequency = scanResult.frequency;

		// 是否安全,微信的标准是是否需要密码。 来源:https://developers.weixin.qq.com/community/develop/doc/00064cf1790458db19cddf9925ac00?highLine=WifiInfo
		ret.secure = false;
		let capabilities = scanResult.capabilities.trim();
		if ((capabilities.equals(Global.WIFI_AUTH_OPEN) || capabilities.equals(Global.WIFI_AUTH_ROAM))) {
			ret.secure = false;
		} else {
			ret.secure = true;
打打卡夫卡's avatar
打打卡夫卡 已提交
151
		}
杜庆泉's avatar
杜庆泉 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165

		/*扩展字段*/
		ret.securityType = getSecurityType(scanResult);
	}

	return ret
}

function wrapUniWifiInfoFromConnectInfo(connectInfo : WifiInfo) : UniWifiInfo {
	let ret : UniWifiInfo = {
		SSID: "",
		secure: false,
		signalStrength: 0,
		frequency: 0,
杜庆泉's avatar
杜庆泉 已提交
166
	}
杜庆泉's avatar
杜庆泉 已提交
167 168
	
	
杜庆泉's avatar
杜庆泉 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
	if (connectInfo.getSSID() != null) {
		let s = connectInfo.getSSID();
		// 微信不带,这里需要去掉引号
		if (s.length > 2 && s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') {
			s = s.substring(1, s.length - 1);
		}
		ret.SSID = s;
	}

	ret.BSSID = connectInfo.getBSSID();
	//Android返回的值是-100~0,而微信API规范是0~100,值越大信号越好,需要+100拉齐
	ret.signalStrength = connectInfo.getRssi() + 100;
	ret.frequency = connectInfo.getFrequency();


	return ret
杜庆泉's avatar
杜庆泉 已提交
185 186
}

杜庆泉's avatar
杜庆泉 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

// /**
//  * Wifi信息统一数据结构
//  */
// class UniWifiInfo {

// 	SSID: string = "";
// 	BSSID: string = "";
// 	secure: boolean = false;
// 	signalStrength: Number = 0;
// 	frequency: Number = 0;

// 	/*下面的字段属于扩展字段*/
// 	securityType:string = ""

// 	constructor(scanResult: ScanResult|null = null) {
// 		if (scanResult != null) {
// 			// 如果是通过扫描列表得到的数据,进行封装
// 			this.BSSID = scanResult.BSSID;
// 			this.SSID = scanResult.SSID;

// 			this.signalStrength = scanResult.level;
// 			this.frequency = scanResult.frequency;

// 			// 是否安全,微信的标准是是否需要密码。 来源:https://developers.weixin.qq.com/community/develop/doc/00064cf1790458db19cddf9925ac00?highLine=WifiInfo
// 			this.secure = false;
// 			let capabilities = scanResult.capabilities.trim();
// 			if ((capabilities.equals(Global.WIFI_AUTH_OPEN) || capabilities.equals(Global.WIFI_AUTH_ROAM))) {
// 				this.secure = false;
// 			} else {
// 				this.secure = true;
// 			}

// 			/*扩展字段*/
// 			this.securityType = getSecurityType(scanResult);
// 		}
// 	}

// 	/**
// 	 * 根据connectInfo 链接信息对wifi数据结构进行初始化
// 	 */
// 	wrapConnectInfo(connectInfo: WifiInfo): void {

// 		if (connectInfo.getBSSID() == null) {
// 			return
// 		}
// 		if (connectInfo.getSSID() != null) {
// 			let s = connectInfo.getSSID();
// 			// 微信不带,这里需要去掉引号
// 			if (s.length > 2 && s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') {
// 				s = s.substring(1, s.length - 1);
// 			}
// 			this.SSID = s;
// 		}

// 			this.BSSID = connectInfo.getBSSID();
// 			//Android返回的值是-100~0,而微信API规范是0~100,值越大信号越好,需要+100拉齐
// 			this.signalStrength = connectInfo.getRssi() + 100; 
// 			this.frequency = connectInfo.getFrequency();

// 	}


// }

杜庆泉's avatar
杜庆泉 已提交
252
/**
杜庆泉's avatar
杜庆泉 已提交
253 254
	* 连接wifi时使用,根据用户输入内容包装为系统需要的wifi配置对象
	*/
杜庆泉's avatar
杜庆泉 已提交
255
@Suppress("DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
256 257
function wrapWifiConfiguration(SSID : string, password ?: string, passwordType : string) : WifiConfiguration {

杜庆泉's avatar
杜庆泉 已提交
258
	let config = new WifiConfiguration();
杜庆泉's avatar
杜庆泉 已提交
259
	config.status = WifiConfiguration.Status.ENABLED;
杜庆泉's avatar
杜庆泉 已提交
260 261 262 263 264
	config.allowedAuthAlgorithms.clear();
	config.allowedGroupCiphers.clear();
	config.allowedKeyManagement.clear();
	config.allowedPairwiseCiphers.clear();
	config.allowedProtocols.clear();
杜庆泉's avatar
杜庆泉 已提交
265
	config.SSID = "\"".concat(SSID).concat("\"");
杜庆泉's avatar
杜庆泉 已提交
266 267


杜庆泉's avatar
杜庆泉 已提交
268
	// nopass
杜庆泉's avatar
杜庆泉 已提交
269
	if ("NONE".equals(passwordType) || password == null) {
杜庆泉's avatar
杜庆泉 已提交
270 271 272
		config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
	}
	// wep
杜庆泉's avatar
杜庆泉 已提交
273 274
	else if ("WEP".equals(passwordType)) {
		if (password != null && !TextUtils.isEmpty(password)) {
杜庆泉's avatar
杜庆泉 已提交
275 276 277 278 279 280 281 282 283 284 285 286
			if (isHexWepKey(password)) {
				config.wepKeys[0] = password;
			} else {
				config.wepKeys[0] = "\"".concat(password).concat("\"");
			}
		}
		config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
		config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
		config.allowedKeyManagement.set(KeyMgmt.NONE);
		config.wepTxKeyIndex = 0;
	}
	// wpa
杜庆泉's avatar
杜庆泉 已提交
287
	else if ("WPA".equals(passwordType)) {
杜庆泉's avatar
杜庆泉 已提交
288 289 290 291 292 293 294 295 296 297 298
		config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
		config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
		config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
		config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
		config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
		config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
		config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
		config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
		config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
		config.preSharedKey = "\"".concat(password).concat("\"");
	}
杜庆泉's avatar
杜庆泉 已提交
299

杜庆泉's avatar
杜庆泉 已提交
300
	return config;
301 302
}

杜庆泉's avatar
杜庆泉 已提交
303 304

/**
杜庆泉's avatar
杜庆泉 已提交
305 306 307 308 309 310 311 312 313 314 315
	* 判断当前wifi的加密类型
	*/
function getSecurityType(result : ScanResult) : string {
	if (result.capabilities.contains("WEP")) {
		return "WEP";
	} else if (result.capabilities.contains("PSK")) {
		return "WPA";
	} else if (result.capabilities.contains("EAP")) {
		return "EAP";
	}
	return "NONE";
杜庆泉's avatar
杜庆泉 已提交
316 317 318
}


杜庆泉's avatar
杜庆泉 已提交
319 320 321 322
function zeroCountNum(source? : string) : number {
	if(source == null){
		return 0
	}
杜庆泉's avatar
杜庆泉 已提交
323 324
	var splitted = source.split(":")
	var countNum = 0;
杜庆泉's avatar
杜庆泉 已提交
325 326
	for (perItem in splitted) {
		if (perItem == "00") {
杜庆泉's avatar
杜庆泉 已提交
327 328 329 330 331
			countNum += 1
		}
	}
	return countNum
}
杜庆泉's avatar
杜庆泉 已提交
332
/**
杜庆泉's avatar
杜庆泉 已提交
333 334 335
	* 自定义wifi变化广播监听器
	*/
@Suppress("UNUSED_PARAMETER", "DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
336
class CustomBroadcastReceiver extends BroadcastReceiver {
杜庆泉's avatar
杜庆泉 已提交
337

杜庆泉's avatar
杜庆泉 已提交
338
	mWifiManager : WifiManager | null = null;
杜庆泉's avatar
杜庆泉 已提交
339

杜庆泉's avatar
杜庆泉 已提交
340
	constructor(wifiManager : WifiManager) {
杜庆泉's avatar
杜庆泉 已提交
341 342 343
		super();
		this.mWifiManager = wifiManager;
	}
杜庆泉's avatar
杜庆泉 已提交
344

杜庆泉's avatar
杜庆泉 已提交
345
	override onReceive(_context : Context, intent : Intent) : void {
杜庆泉's avatar
杜庆泉 已提交
346 347


杜庆泉's avatar
杜庆泉 已提交
348 349 350 351 352
		if (intent.action == WifiManager.WIFI_STATE_CHANGED_ACTION) {
			let state =
				intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
			if (state == WifiManager.WIFI_STATE_ENABLED) {
				// 获取当前的connectInfo 并且进行数据封装
杜庆泉's avatar
杜庆泉 已提交
353 354 355 356 357 358 359
				// let uniWifiInfo = new UniWifiInfo(null)
				let uniWifiInfo : UniWifiInfo = {
					SSID: "",
					secure: false,
					signalStrength: 0,
					frequency: 0,
				}
杜庆泉's avatar
杜庆泉 已提交
360
				//做一些异步操作
杜庆泉's avatar
杜庆泉 已提交
361
				setTimeout(function () {
杜庆泉's avatar
杜庆泉 已提交
362
					// BroadcastReceiver 中不能执行耗时任务,需要使用setTimeout
打打卡夫卡's avatar
打打卡夫卡 已提交
363
					// @ts-ignore
杜庆泉's avatar
杜庆泉 已提交
364
					let winfo = this.mWifiManager!.getConnectionInfo();
杜庆泉's avatar
杜庆泉 已提交
365

杜庆泉's avatar
杜庆泉 已提交
366
					while (winfo.bssid == null || zeroCountNum(winfo.bssid) > 4) {
杜庆泉's avatar
杜庆泉 已提交
367
						Thread.sleep(1000)
打打卡夫卡's avatar
打打卡夫卡 已提交
368
						winfo = this.mWifiManager!.getConnectionInfo();
杜庆泉's avatar
杜庆泉 已提交
369 370 371
					}

					// 封装成数据对象
杜庆泉's avatar
杜庆泉 已提交
372
					uniWifiInfo = wrapUniWifiInfoFromConnectInfo(winfo)
杜庆泉's avatar
杜庆泉 已提交
373 374 375 376 377 378 379 380 381
					let res = {
						errMsg: 'onWifiConnected:ok',
						errCode: 0,
						wifi: uniWifiInfo
					}
					// wifi状态可用了,分发当前的链接状态给已注册的监听集合
					for (let perCallback in Global.onWifiConnectCallbackList) {
						perCallback(res);
					}
杜庆泉's avatar
杜庆泉 已提交
382 383
					// 封装仅SSID 数据对象
					var connectedWithPartialInfo = {
杜庆泉's avatar
杜庆泉 已提交
384
						SSID: uniWifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
385 386 387 388
					}
					for (let perCallback in Global.onWifiConnectWithPartialInfoCallbackList) {
						perCallback(connectedWithPartialInfo);
					}
杜庆泉's avatar
杜庆泉 已提交
389 390 391 392

				}, 100);
			}

杜庆泉's avatar
杜庆泉 已提交
393
		}
杜庆泉's avatar
杜庆泉 已提交
394 395


杜庆泉's avatar
杜庆泉 已提交
396
		if (intent.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
杜庆泉's avatar
杜庆泉 已提交
397 398
			// wifi 扫描结果回调
			let results = this.mWifiManager!.scanResults;
杜庆泉's avatar
杜庆泉 已提交
399

杜庆泉's avatar
杜庆泉 已提交
400 401
			if (results != null) {
				Global.scanList = []
杜庆泉's avatar
杜庆泉 已提交
402 403 404
				for (let scanResult in results) {
					if (scanResult.SSID == null) {
						continue;
杜庆泉's avatar
杜庆泉 已提交
405
					}
杜庆泉's avatar
杜庆泉 已提交
406
					Global.scanList.push(wrapUniWifiInfoFromScan(scanResult));
杜庆泉's avatar
杜庆泉 已提交
407
				}
杜庆泉's avatar
杜庆泉 已提交
408

杜庆泉's avatar
杜庆泉 已提交
409
				// 挨个通知,所有的监听器
杜庆泉's avatar
杜庆泉 已提交
410 411
				for (let perCallback in Global.getWifiListCallbackList) {

杜庆泉's avatar
杜庆泉 已提交
412
					const data = new JSONObject();
杜庆泉's avatar
杜庆泉 已提交
413 414
					// let mainJsonStr = Gson().toJson(Global.scanList);
					data["wifiList"] = Global.scanList
杜庆泉's avatar
杜庆泉 已提交
415 416
					perCallback(data);
				}
杜庆泉's avatar
杜庆泉 已提交
417

杜庆泉's avatar
杜庆泉 已提交
418
			}
杜庆泉's avatar
杜庆泉 已提交
419

杜庆泉's avatar
杜庆泉 已提交
420 421
		}
	}
杜庆泉's avatar
杜庆泉 已提交
422

杜庆泉's avatar
杜庆泉 已提交
423 424
}

425 426


杜庆泉's avatar
杜庆泉 已提交
427 428
/************************* 下面是对外提供的函数 *************************/

杜庆泉's avatar
杜庆泉 已提交
429
/**
杜庆泉's avatar
杜庆泉 已提交
430 431
	* 开启wifi
	*/
杜庆泉's avatar
杜庆泉 已提交
432
@Suppress("DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
433 434
export function startWifi(option : WifiOption) {

杜庆泉's avatar
杜庆泉 已提交
435 436 437
	// 需要先开启wifi,才能使用后续的功能
	let requestCode = 1001;
	let permissionWifi = arrayOf("android.permission.ACCESS_FINE_LOCATION");
杜庆泉's avatar
杜庆泉 已提交
438
	var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
439 440
		errCode: 12001,
		errMsg: "startWifi:premission loss",
杜庆泉's avatar
杜庆泉 已提交
441
		errSubject: "uni-startWifi"
杜庆泉's avatar
杜庆泉 已提交
442 443 444 445 446 447 448 449 450 451 452 453 454
	}
	// 检查权限
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

		ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, permissionWifi, requestCode)
		// 尚不具备权限,返回错误
		option.fail?.(result)
		option.complete?.(result)

		return;
	}

	// 具备了权限,继续前进
杜庆泉's avatar
杜庆泉 已提交
455
	let wifiManager : WifiManager =
杜庆泉's avatar
杜庆泉 已提交
456 457
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
	// 用户没有开启wifi 总开关
杜庆泉's avatar
杜庆泉 已提交
458
	if (!wifiManager.isWifiEnabled()) {
杜庆泉's avatar
杜庆泉 已提交
459 460 461
		// wifi 没开启
		result.errCode = 12005;
		result.errMsg = "wifi not turned on";
杜庆泉's avatar
杜庆泉 已提交
462

杜庆泉's avatar
杜庆泉 已提交
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
		option.fail?.(result);
		option.complete?.(result);
		return;
	}
	// 初始化wifi 状态广播监听,后续所有的api,均基于此
	if (Global.mReceiver == null) {
		Global.mReceiver = new CustomBroadcastReceiver(wifiManager)
	}

	let filter = new IntentFilter()
	filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
	// @ts-ignore
	filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
	// @ts-ignore
	filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
杜庆泉's avatar
杜庆泉 已提交
478

杜庆泉's avatar
杜庆泉 已提交
479
	UTSAndroid.getUniActivity()!.registerReceiver(Global.mReceiver, filter)
杜庆泉's avatar
杜庆泉 已提交
480

杜庆泉's avatar
杜庆泉 已提交
481
	/**
杜庆泉's avatar
杜庆泉 已提交
482 483 484 485 486
		* activity 被销毁时,取消注册
		*/
	UTSAndroid.onAppActivityDestroy(function () {

		if (Global.mReceiver != null) {
杜庆泉's avatar
杜庆泉 已提交
487 488
			UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
			Global.mReceiver = null
杜庆泉's avatar
杜庆泉 已提交
489

杜庆泉's avatar
杜庆泉 已提交
490 491 492
			Global.scanList = []
			Global.getWifiListCallbackList = []
			Global.onWifiConnectCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
493
			Global.onWifiConnectWithPartialInfoCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
494
		}
杜庆泉's avatar
杜庆泉 已提交
495

杜庆泉's avatar
杜庆泉 已提交
496 497 498
	});
	// 开始扫描
	wifiManager.startScan()
杜庆泉's avatar
杜庆泉 已提交
499

杜庆泉's avatar
杜庆泉 已提交
500 501
	result.errCode = 0
	result.errMsg = "startWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
502

杜庆泉's avatar
杜庆泉 已提交
503 504 505 506 507
	option.success?.(result)
	option.complete?.(result)

}

杜庆泉's avatar
杜庆泉 已提交
508
/**
杜庆泉's avatar
杜庆泉 已提交
509 510
	* 获取wifi列表
	*/
511
@Suppress("DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
512 513 514
export function getWifiList(option : WifiOption) {

	var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
515 516
		errCode: 12000,
		errMsg: "getWifiList:fail:not invoke startWifi",
杜庆泉's avatar
杜庆泉 已提交
517
		errSubject: "uni-getWifiList"
杜庆泉's avatar
杜庆泉 已提交
518
	}
杜庆泉's avatar
杜庆泉 已提交
519

520 521 522 523
	if (Global.mReceiver == null) {
		// 还没调用startWifi 提示报错
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
524

525 526
		return
	}
杜庆泉's avatar
杜庆泉 已提交
527 528

	let wifiManager : WifiManager =
529
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
杜庆泉's avatar
杜庆泉 已提交
530

杜庆泉's avatar
杜庆泉 已提交
531 532
	wifiManager.startScan()

杜庆泉's avatar
杜庆泉 已提交
533
	let ret : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
534
		errCode: 0,
杜庆泉's avatar
杜庆泉 已提交
535
		errSubject: "uni-getWifiList",
杜庆泉's avatar
杜庆泉 已提交
536
		errMsg: "getWifiList:ok"
杜庆泉's avatar
杜庆泉 已提交
537
	}
打打卡夫卡's avatar
打打卡夫卡 已提交
538 539
	option.success?.(ret)
	option.complete?.(ret)
杜庆泉's avatar
杜庆泉 已提交
540

杜庆泉's avatar
杜庆泉 已提交
541 542 543
}


杜庆泉's avatar
杜庆泉 已提交
544

杜庆泉's avatar
杜庆泉 已提交
545
/**
杜庆泉's avatar
杜庆泉 已提交
546 547 548
	* wifi 链接成功的回调注册
	*/
export function onWifiConnected(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
549 550 551
	Global.onWifiConnectCallbackList.push(callback)
}

杜庆泉's avatar
杜庆泉 已提交
552

杜庆泉's avatar
杜庆泉 已提交
553
export function onWifiConnectedWithPartialInfo(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
554 555 556 557
	Global.onWifiConnectWithPartialInfoCallbackList.push(callback)
}


杜庆泉's avatar
杜庆泉 已提交
558
/**
杜庆泉's avatar
杜庆泉 已提交
559 560 561
	* wifi 链接成功的回调取消注册
	*/
export function offWifiConnected(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
562
	let callbackIndex = Global.onWifiConnectCallbackList.indexOf(callback)
杜庆泉's avatar
杜庆泉 已提交
563 564
	if (callbackIndex > 0) {
		Global.onWifiConnectCallbackList.splice(callbackIndex, 1);
杜庆泉's avatar
杜庆泉 已提交
565 566 567
	}
}

杜庆泉's avatar
杜庆泉 已提交
568
export function offWifiConnectedWithPartialInfo(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
569 570 571 572 573 574
	let callbackIndex = Global.onWifiConnectWithPartialInfoCallbackList.indexOf(callback)
	if (callbackIndex > 0) {
		Global.onWifiConnectWithPartialInfoCallbackList.splice(callbackIndex, 1);
	}
}

杜庆泉's avatar
杜庆泉 已提交
575
/**
杜庆泉's avatar
杜庆泉 已提交
576 577 578
	* 注册Wifi列表的监听事件
	*/
export function onGetWifiList(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
579 580 581
	Global.getWifiListCallbackList.push(callback)
}
/**
杜庆泉's avatar
杜庆泉 已提交
582 583 584
	* 取消注册Wifi列表的监听事件
	*/
export function offGetWifiList(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
585
	let callbackIndex = Global.getWifiListCallbackList.indexOf(callback)
杜庆泉's avatar
杜庆泉 已提交
586 587
	if (callbackIndex > 0) {
		Global.getWifiListCallbackList.splice(callbackIndex, 1);
杜庆泉's avatar
杜庆泉 已提交
588 589 590
	}
}

杜庆泉's avatar
杜庆泉 已提交
591 592

/**
杜庆泉's avatar
杜庆泉 已提交
593 594 595 596
	* 链接指定wifi
	*/
@Suppress("UNUSED_PARAMETER", "DEPRECATION")
export function connectWifi(option : WifiConnectOption) {
597

杜庆泉's avatar
杜庆泉 已提交
598 599

	var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
600 601
		errCode: 12000,
		errMsg: "connectWifi:fail:not invoke startWifi",
杜庆泉's avatar
杜庆泉 已提交
602
		errSubject: "uni-connectWifi",
杜庆泉's avatar
杜庆泉 已提交
603
	}
杜庆泉's avatar
杜庆泉 已提交
604

杜庆泉's avatar
杜庆泉 已提交
605 606 607 608
	if (Global.mReceiver == null || Global.scanList.length < 1) {
		// 还没调用startWifi 提示报错
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
609

杜庆泉's avatar
杜庆泉 已提交
610 611
		return
	}
杜庆泉's avatar
杜庆泉 已提交
612 613

	if (option.maunal == true) {
614 615
		// 指定了手动模式
		let manunalIntent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
616
		UTSAndroid.getUniActivity()!.startActivity(manunalIntent);
杜庆泉's avatar
杜庆泉 已提交
617

618 619
		result.errCode = 0
		result.errMsg = "connectWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
620

621 622
		option.success?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
623
		return
624
	}
杜庆泉's avatar
杜庆泉 已提交
625

杜庆泉's avatar
杜庆泉 已提交
626
	// 执行后续的逻辑
杜庆泉's avatar
杜庆泉 已提交
627
	let scanWifiInfo : AndroidUniWifiInfo | null = null
杜庆泉's avatar
杜庆泉 已提交
628 629 630 631 632
	for (let scanResult in Global.scanList) {
		if (scanResult.SSID.equals(option.SSID)) {
			scanWifiInfo = scanResult
		}
	}
杜庆泉's avatar
杜庆泉 已提交
633 634

	if (scanWifiInfo == null) {
杜庆泉's avatar
杜庆泉 已提交
635 636 637 638 639
		// 不在扫描列表中返回错误
		option.fail?.(result)
		option.complete?.(result)
		return
	}
杜庆泉's avatar
杜庆泉 已提交
640 641

	let wifiConfigration = wrapWifiConfiguration(scanWifiInfo.SSID, option.password, scanWifiInfo.securityType);
杜庆泉's avatar
杜庆泉 已提交
642
	wifiConfigration.BSSID = scanWifiInfo.BSSID
杜庆泉's avatar
杜庆泉 已提交
643
	let wifiManager : WifiManager =
644
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
杜庆泉's avatar
杜庆泉 已提交
645

646
	// 如果已经存在了指定wifi 配置,移除之
杜庆泉's avatar
杜庆泉 已提交
647
	let targetExistConfig : WifiConfiguration | null = null
杜庆泉's avatar
杜庆泉 已提交
648 649 650 651 652 653
	let existingConfigs = wifiManager.getConfiguredNetworks();
	for (let existingConfig in existingConfigs) {
		if (existingConfig.SSID.equals("\"" + option.SSID + "\"")) {
			targetExistConfig = existingConfig
		}
	}
杜庆泉's avatar
杜庆泉 已提交
654
	// 如果wifi已经保存了当前ssid的配置,可能是别的应用添加的。android系统要求,需要删除掉重新添加
杜庆泉's avatar
杜庆泉 已提交
655
	if (targetExistConfig != null) {
杜庆泉's avatar
杜庆泉 已提交
656
		let removeRet = wifiManager.removeNetwork(targetExistConfig.networkId);
杜庆泉's avatar
杜庆泉 已提交
657 658

		if (!removeRet) {
杜庆泉's avatar
杜庆泉 已提交
659 660 661
			// 移除之前的配置失败了,返回错误,需要用户手动取消保存一下
			result.errCode = 12013
			result.errMsg = "connectWifi:wifi config may be expired"
杜庆泉's avatar
杜庆泉 已提交
662

杜庆泉's avatar
杜庆泉 已提交
663 664
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
665

杜庆泉's avatar
杜庆泉 已提交
666 667
			return
		}
杜庆泉's avatar
杜庆泉 已提交
668

杜庆泉's avatar
杜庆泉 已提交
669
	}
杜庆泉's avatar
杜庆泉 已提交
670

杜庆泉's avatar
杜庆泉 已提交
671
	let currentConnect = wifiManager.getConnectionInfo()
杜庆泉's avatar
杜庆泉 已提交
672 673 674
	if (currentConnect.networkId >= 0) {
		wifiManager.disableNetwork(currentConnect.networkId)
	} else {
杜庆泉's avatar
杜庆泉 已提交
675
		wifiManager.removeNetwork(currentConnect.networkId)
杜庆泉's avatar
杜庆泉 已提交
676
	}
杜庆泉's avatar
杜庆泉 已提交
677
	wifiManager.disconnect()
杜庆泉's avatar
杜庆泉 已提交
678

杜庆泉's avatar
杜庆泉 已提交
679
	let connected = false;
680
	try {
杜庆泉's avatar
杜庆泉 已提交
681

682
		let netID = wifiManager.addNetwork(wifiConfigration);
杜庆泉's avatar
杜庆泉 已提交
683
		// 如果-1 说明没添加上,报错即可
杜庆泉's avatar
杜庆泉 已提交
684
		if (netID < 0) {
杜庆泉's avatar
杜庆泉 已提交
685 686
			result.errCode = 12002
			result.errMsg = "connectWifi:password error Wi-Fi"
杜庆泉's avatar
杜庆泉 已提交
687

杜庆泉's avatar
杜庆泉 已提交
688 689
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
690

杜庆泉's avatar
杜庆泉 已提交
691 692
			return
		}
杜庆泉's avatar
杜庆泉 已提交
693 694


695
		let enabled = wifiManager.enableNetwork(netID, true);
杜庆泉's avatar
杜庆泉 已提交
696 697
		if (!enabled) {

杜庆泉's avatar
杜庆泉 已提交
698 699
			result.errCode = 12007
			result.errMsg = "connectWifi:user denied"
杜庆泉's avatar
杜庆泉 已提交
700

杜庆泉's avatar
杜庆泉 已提交
701 702
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
703

杜庆泉's avatar
杜庆泉 已提交
704 705
			return
		}
杜庆泉's avatar
杜庆泉 已提交
706
		connected = wifiManager.reconnect();
杜庆泉's avatar
杜庆泉 已提交
707

708
	} catch (e) {
杜庆泉's avatar
杜庆泉 已提交
709
		connected = false;
710 711
		console.log(e);
	}
杜庆泉's avatar
杜庆泉 已提交
712 713

	if (!connected) {
杜庆泉's avatar
杜庆泉 已提交
714
		// 出错了,返回错误
杜庆泉's avatar
杜庆泉 已提交
715 716 717
		// 兜底的报错
		result.errCode = 12010
		result.errMsg = "connectWifi:fail:unknown error"
杜庆泉's avatar
杜庆泉 已提交
718

杜庆泉's avatar
杜庆泉 已提交
719 720
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
721
		return
打打卡夫卡's avatar
打打卡夫卡 已提交
722
	}
杜庆泉's avatar
杜庆泉 已提交
723

杜庆泉's avatar
杜庆泉 已提交
724 725
	wifiManager.saveConfiguration()
	//scanWifiInfo 根据 partialInfo 填充给返回字段
杜庆泉's avatar
杜庆泉 已提交
726 727 728
	if (option.partialInfo != null && option.partialInfo == true) {
		let wifiPartialInfo:UniWifiInfo = {
			SSID: scanWifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
729
		}
杜庆泉's avatar
杜庆泉 已提交
730 731 732
		result.wifi =wifiPartialInfo
	} else {
		result.wifi = wrapUniWifiInfoFromAndroid(scanWifiInfo)
杜庆泉's avatar
杜庆泉 已提交
733
	}
杜庆泉's avatar
杜庆泉 已提交
734

杜庆泉's avatar
杜庆泉 已提交
735
	// result.wifi = scanWifiInfo.toUTSJSON(option.partialInfo)
打打卡夫卡's avatar
打打卡夫卡 已提交
736
	result.errCode = 0
杜庆泉's avatar
杜庆泉 已提交
737
	result.errMsg = "connectWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
738

杜庆泉's avatar
杜庆泉 已提交
739 740
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
741

742 743
}

杜庆泉's avatar
杜庆泉 已提交
744 745

/**
杜庆泉's avatar
杜庆泉 已提交
746 747 748
	* 关闭wifi
	*/
export function stopWifi(option : WifiOption) {
杜庆泉's avatar
杜庆泉 已提交
749 750
	// 需要先开启wifi,才能使用后续的功能
	if (Global.mReceiver == null) {
杜庆泉's avatar
杜庆泉 已提交
751
		var result:UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
752
			errCode: 12000,
杜庆泉's avatar
杜庆泉 已提交
753
			errSubject:"uni-stopWifi",
杜庆泉's avatar
杜庆泉 已提交
754
			errMsg: "stopWifi:not init"
杜庆泉's avatar
杜庆泉 已提交
755 756 757
		}
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
758 759

		return
杜庆泉's avatar
杜庆泉 已提交
760
	}
杜庆泉's avatar
杜庆泉 已提交
761
	try {
762
		UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
杜庆泉's avatar
杜庆泉 已提交
763
	} catch (e) {
764 765 766
		// 多次调用
		//TODO handle the exception
	}
杜庆泉's avatar
杜庆泉 已提交
767 768

	var result:UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
769
		errCode: 0,
杜庆泉's avatar
杜庆泉 已提交
770
		errSubject:"uni-stopWifi",
杜庆泉's avatar
杜庆泉 已提交
771
		errMsg: "stopWifi:ok"
772
	}
杜庆泉's avatar
杜庆泉 已提交
773 774
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
775

杜庆泉's avatar
杜庆泉 已提交
776 777 778
}

/**
杜庆泉's avatar
杜庆泉 已提交
779 780
	* 获取当前连接中的wifi信息
	*/
781
@Suppress("DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
782
export function getConnectedWifi(option : GetConnectedWifiOptions) {
杜庆泉's avatar
杜庆泉 已提交
783

杜庆泉's avatar
杜庆泉 已提交
784 785 786
	let wifiInfo:UniWifiInfo = {
		SSID:""
	}
打打卡夫卡's avatar
打打卡夫卡 已提交
787

杜庆泉's avatar
杜庆泉 已提交
788
	var res:UniWifiResult = {
打打卡夫卡's avatar
打打卡夫卡 已提交
789 790
		errCode: 12000,
		errMsg: "getConnectedWifi:fail:not invoke startWifi",
杜庆泉's avatar
杜庆泉 已提交
791
		errSubject: "uni-getConnectedWifi",
打打卡夫卡's avatar
打打卡夫卡 已提交
792 793
	}

794
	if (Global.mReceiver == null) {
打打卡夫卡's avatar
打打卡夫卡 已提交
795 796 797
		// 还没调用startWifi 提示报错
		option.fail?.(res)
		option.complete?.(res)
杜庆泉's avatar
杜庆泉 已提交
798

799 800
		return
	}
杜庆泉's avatar
杜庆泉 已提交
801

802
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
杜庆泉's avatar
杜庆泉 已提交
803
		// 尚不具备权限,返回错误
打打卡夫卡's avatar
打打卡夫卡 已提交
804 805
		res.errCode = 12001
		res.errMsg = "getConnectedWifi:permission loss"
杜庆泉's avatar
杜庆泉 已提交
806

杜庆泉's avatar
杜庆泉 已提交
807 808 809
		option.fail?.(res)
		option.complete?.(res)
		return;
杜庆泉's avatar
杜庆泉 已提交
810 811
	}

812 813
	// TODO 应该try catch一下,把系统的错误码给返回来,然后和微信的错误码拉齐
	// 需要先校验权限,没有位置权限无法获取wifi
814
	const context = UTSAndroid.getAppContext();
815
	if (context != null) {
杜庆泉's avatar
杜庆泉 已提交
816 817 818
		const wm = context.getSystemService(
			Context.WIFI_SERVICE
		) as WifiManager;
杜庆泉's avatar
杜庆泉 已提交
819
		// 测试android 12上可以使用
打打卡夫卡's avatar
打打卡夫卡 已提交
820
		//@ts-ignore
杜庆泉's avatar
杜庆泉 已提交
821
		const winfo = wm.getConnectionInfo();
杜庆泉's avatar
杜庆泉 已提交
822 823

		wifiInfo = wrapUniWifiInfoFromConnectInfo(winfo);
杜庆泉's avatar
杜庆泉 已提交
824
		// 判断一下是否wifi 关闭了
杜庆泉's avatar
杜庆泉 已提交
825 826 827
		if (option.partialInfo!) {
			let ret:UniWifiInfo = {
				SSID: wifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
828
			}
杜庆泉's avatar
杜庆泉 已提交
829 830 831
			res.wifi = ret;
		} else {
			if (wifiInfo.BSSID == null || zeroCountNum(wifiInfo.BSSID) > 3) {
杜庆泉's avatar
杜庆泉 已提交
832 833
				res.errCode = 12005
				res.errMsg = "getConnectedWifi:fail:wifi is disable"
杜庆泉's avatar
杜庆泉 已提交
834

杜庆泉's avatar
杜庆泉 已提交
835 836 837 838
				option.fail?.(res)
				option.complete?.(res)
				return
			}
杜庆泉's avatar
杜庆泉 已提交
839
			res.wifi = wifiInfo;
杜庆泉's avatar
杜庆泉 已提交
840
		}
杜庆泉's avatar
杜庆泉 已提交
841

杜庆泉's avatar
杜庆泉 已提交
842 843
		res.errCode = 0
		res.errMsg = "getConnectedWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
844

杜庆泉's avatar
杜庆泉 已提交
845 846 847
		option.success?.(res)
		option.complete?.(res)
		return
848
	}
杜庆泉's avatar
杜庆泉 已提交
849 850
	option.fail?.(res)
	option.complete?.(res)
851
}