index.uts 21.2 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';
杜庆泉's avatar
杜庆泉 已提交
19
import Build from 'android.os.Build';
20

杜庆泉's avatar
杜庆泉 已提交
21
import { UniWifiResult, GetConnectedWifiOptions, WifiConnectOption, WifiOption, UniWifiInfo } from "../interface.uts"
杜庆泉's avatar
杜庆泉 已提交
22

杜庆泉's avatar
杜庆泉 已提交
23 24 25


/**
杜庆泉's avatar
杜庆泉 已提交
26 27
	* 全局数据储存
	*/
杜庆泉's avatar
杜庆泉 已提交
28
class Global {
杜庆泉's avatar
杜庆泉 已提交
29 30 31
	static mReceiver : CustomBroadcastReceiver | null = null;
	static WIFI_AUTH_OPEN : string = "";
	static WIFI_AUTH_ROAM : String = "[ESS]";
杜庆泉's avatar
杜庆泉 已提交
32
	// 扫描wifi结果
杜庆泉's avatar
杜庆泉 已提交
33
	static scanList : AndroidUniWifiInfo[] = []
杜庆泉's avatar
杜庆泉 已提交
34
	// 获取wifi列表监听
杜庆泉's avatar
杜庆泉 已提交
35 36 37
	static onGetWifiListCallback : UTSCallback | null = null
	static supendGetWifiSuccess : ((res: UniWifiResult) => void) | null = null
	static supendGetWifiComplete : ((res: UniWifiResult) => void) | null = null
杜庆泉's avatar
杜庆泉 已提交
38
	// wifi链接监听
杜庆泉's avatar
杜庆泉 已提交
39 40
	static onWifiConnectCallbackList : UTSCallback[] = []
	static onWifiConnectWithPartialInfoCallbackList : UTSCallback[] = []
杜庆泉's avatar
杜庆泉 已提交
41 42 43
}


44
/**
杜庆泉's avatar
杜庆泉 已提交
45 46 47
	* 是否是标准的16进制字符
	*/
function isHex(key : string) : boolean {
48 49 50
	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
杜庆泉 已提交
51
			&& c <= 'f')) {
52 53 54 55 56 57 58 59
			return false;
		}
	}

	return true;
}

/**
杜庆泉's avatar
杜庆泉 已提交
60 61 62
	* 判断是否是wep格式的key
	*/
function isHexWepKey(wepKey : string) : boolean {
63 64 65 66 67 68 69 70 71
	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
杜庆泉 已提交
72 73 74
/**
 * android 平台特有的Wifi信息对象,主要是加了加密信息这个字段
 */
杜庆泉's avatar
杜庆泉 已提交
75 76 77 78 79 80 81 82
export type AndroidUniWifiInfo = {
	SSID : string;
	BSSID ?: string;
	secure : boolean;
	signalStrength : number;
	frequency : number;
	securityType : string;
}
杜庆泉's avatar
杜庆泉 已提交
83

杜庆泉's avatar
杜庆泉 已提交
84
function wrapUniWifiInfoFromAndroid(androidInfo : AndroidUniWifiInfo) : UniWifiInfo {
杜庆泉's avatar
杜庆泉 已提交
85 86 87 88 89 90
	let ret : UniWifiInfo = {
		SSID: androidInfo.SSID,
		BSSID: androidInfo.BSSID,
		secure: androidInfo.secure,
		signalStrength: androidInfo.signalStrength,
		frequency: androidInfo.frequency,
杜庆泉's avatar
杜庆泉 已提交
91
	}
杜庆泉's avatar
杜庆泉 已提交
92 93
	return ret
}
杜庆泉's avatar
杜庆泉 已提交
94 95 96
/**
 * 从扫描结果中提取统一的wifi数据结构
 */
杜庆泉's avatar
杜庆泉 已提交
97 98 99 100 101 102 103
function wrapUniWifiInfoFromScan(scanResult : ScanResult) : AndroidUniWifiInfo {

	let ret : AndroidUniWifiInfo = {
		SSID: "",
		secure: false,
		signalStrength: 0,
		frequency: 0,
杜庆泉's avatar
杜庆泉 已提交
104
		securityType: "NONE"
杜庆泉's avatar
杜庆泉 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	}
	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
打打卡夫卡 已提交
121
		}
杜庆泉's avatar
杜庆泉 已提交
122 123 124 125 126 127 128

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

	return ret
}
杜庆泉's avatar
杜庆泉 已提交
129 130 131
/**
 * 从链接信息中提取统一的wifi数据结构
 */
杜庆泉's avatar
杜庆泉 已提交
132 133 134 135 136 137
function wrapUniWifiInfoFromConnectInfo(connectInfo : WifiInfo) : UniWifiInfo {
	let ret : UniWifiInfo = {
		SSID: "",
		secure: false,
		signalStrength: 0,
		frequency: 0,
杜庆泉's avatar
杜庆泉 已提交
138
	}
杜庆泉's avatar
杜庆泉 已提交
139 140


杜庆泉's avatar
杜庆泉 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	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
杜庆泉 已提交
157 158
}

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

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

杜庆泉's avatar
杜庆泉 已提交
166
	let config = new WifiConfiguration();
杜庆泉's avatar
杜庆泉 已提交
167
	config.status = WifiConfiguration.Status.ENABLED;
杜庆泉's avatar
杜庆泉 已提交
168 169 170 171 172
	config.allowedAuthAlgorithms.clear();
	config.allowedGroupCiphers.clear();
	config.allowedKeyManagement.clear();
	config.allowedPairwiseCiphers.clear();
	config.allowedProtocols.clear();
杜庆泉's avatar
杜庆泉 已提交
173
	config.SSID = "\"".concat(SSID).concat("\"");
杜庆泉's avatar
杜庆泉 已提交
174 175


杜庆泉's avatar
杜庆泉 已提交
176
	// nopass
杜庆泉's avatar
杜庆泉 已提交
177
	if ("NONE".equals(passwordType) || password == null) {
杜庆泉's avatar
杜庆泉 已提交
178 179 180
		config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
	}
	// wep
杜庆泉's avatar
杜庆泉 已提交
181 182
	else if ("WEP".equals(passwordType)) {
		if (password != null && !TextUtils.isEmpty(password)) {
杜庆泉's avatar
杜庆泉 已提交
183 184 185 186 187 188 189 190 191 192 193 194
			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
杜庆泉 已提交
195
	else if ("WPA".equals(passwordType)) {
杜庆泉's avatar
杜庆泉 已提交
196 197 198 199 200 201 202 203 204 205 206
		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
杜庆泉 已提交
207

杜庆泉's avatar
杜庆泉 已提交
208
	return config;
209 210
}

杜庆泉's avatar
杜庆泉 已提交
211 212

/**
杜庆泉's avatar
杜庆泉 已提交
213 214 215 216 217 218 219 220 221 222 223
	* 判断当前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
杜庆泉 已提交
224 225 226
}


杜庆泉's avatar
杜庆泉 已提交
227 228
function zeroCountNum(source ?: string) : number {
	if (source == null) {
杜庆泉's avatar
杜庆泉 已提交
229 230
		return 0
	}
杜庆泉's avatar
杜庆泉 已提交
231 232
	var splitted = source.split(":")
	var countNum = 0;
杜庆泉's avatar
杜庆泉 已提交
233 234
	for (perItem in splitted) {
		if (perItem == "00") {
杜庆泉's avatar
杜庆泉 已提交
235 236 237 238 239
			countNum += 1
		}
	}
	return countNum
}
杜庆泉's avatar
杜庆泉 已提交
240 241


杜庆泉's avatar
杜庆泉 已提交
242
/**
杜庆泉's avatar
杜庆泉 已提交
243 244 245
	* 自定义wifi变化广播监听器
	*/
@Suppress("UNUSED_PARAMETER", "DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
246
class CustomBroadcastReceiver extends BroadcastReceiver {
杜庆泉's avatar
杜庆泉 已提交
247

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

杜庆泉's avatar
杜庆泉 已提交
250
	constructor(wifiManager : WifiManager) {
杜庆泉's avatar
杜庆泉 已提交
251 252 253
		super();
		this.mWifiManager = wifiManager;
	}
杜庆泉's avatar
杜庆泉 已提交
254

杜庆泉's avatar
杜庆泉 已提交
255
	override onReceive(_context : Context, intent : Intent) : void {
杜庆泉's avatar
杜庆泉 已提交
256 257


杜庆泉's avatar
杜庆泉 已提交
258 259 260 261 262
		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
杜庆泉 已提交
263 264 265 266 267 268 269
				// let uniWifiInfo = new UniWifiInfo(null)
				let uniWifiInfo : UniWifiInfo = {
					SSID: "",
					secure: false,
					signalStrength: 0,
					frequency: 0,
				}
杜庆泉's avatar
杜庆泉 已提交
270
				//做一些异步操作
杜庆泉's avatar
杜庆泉 已提交
271
				setTimeout(function () {
杜庆泉's avatar
杜庆泉 已提交
272
					// BroadcastReceiver 中不能执行耗时任务,需要使用setTimeout
打打卡夫卡's avatar
打打卡夫卡 已提交
273
					// @ts-ignore
杜庆泉's avatar
杜庆泉 已提交
274
					let winfo = this.mWifiManager!.getConnectionInfo();
杜庆泉's avatar
杜庆泉 已提交
275

杜庆泉's avatar
杜庆泉 已提交
276
					while (winfo.bssid == null || zeroCountNum(winfo.bssid) > 4) {
杜庆泉's avatar
杜庆泉 已提交
277
						Thread.sleep(1000)
打打卡夫卡's avatar
打打卡夫卡 已提交
278
						winfo = this.mWifiManager!.getConnectionInfo();
杜庆泉's avatar
杜庆泉 已提交
279 280 281
					}

					// 封装成数据对象
杜庆泉's avatar
杜庆泉 已提交
282
					uniWifiInfo = wrapUniWifiInfoFromConnectInfo(winfo)
杜庆泉's avatar
杜庆泉 已提交
283 284 285 286 287 288 289 290 291
					let res = {
						errMsg: 'onWifiConnected:ok',
						errCode: 0,
						wifi: uniWifiInfo
					}
					// wifi状态可用了,分发当前的链接状态给已注册的监听集合
					for (let perCallback in Global.onWifiConnectCallbackList) {
						perCallback(res);
					}
杜庆泉's avatar
杜庆泉 已提交
292 293
					// 封装仅SSID 数据对象
					var connectedWithPartialInfo = {
杜庆泉's avatar
杜庆泉 已提交
294
						SSID: uniWifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
295 296 297 298
					}
					for (let perCallback in Global.onWifiConnectWithPartialInfoCallbackList) {
						perCallback(connectedWithPartialInfo);
					}
杜庆泉's avatar
杜庆泉 已提交
299 300 301 302

				}, 100);
			}

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


杜庆泉's avatar
杜庆泉 已提交
306
		if (intent.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
杜庆泉's avatar
杜庆泉 已提交
307
			startWifiScaning = false;
杜庆泉's avatar
杜庆泉 已提交
308 309 310 311 312 313 314 315 316 317 318 319 320
			
			let ret : UniWifiResult = {
				errCode: 0,
				errSubject: "uni-getWifiList",
				errMsg: "getWifiList:ok"
			}
			if(Global.supendGetWifiSuccess != null){
				Global.supendGetWifiSuccess?.(ret)
			}
			if(Global.supendGetWifiComplete != null){
				Global.supendGetWifiComplete?.(ret)
			}
			
杜庆泉's avatar
杜庆泉 已提交
321 322
			// wifi 扫描结果回调
			let results = this.mWifiManager!.scanResults;
杜庆泉's avatar
杜庆泉 已提交
323

杜庆泉's avatar
杜庆泉 已提交
324
			
杜庆泉's avatar
杜庆泉 已提交
325 326
			if (results != null) {
				Global.scanList = []
杜庆泉's avatar
杜庆泉 已提交
327 328 329
				for (let scanResult in results) {
					if (scanResult.SSID == null) {
						continue;
杜庆泉's avatar
杜庆泉 已提交
330
					}
杜庆泉's avatar
杜庆泉 已提交
331
					Global.scanList.push(wrapUniWifiInfoFromScan(scanResult));
杜庆泉's avatar
杜庆泉 已提交
332
				}
杜庆泉's avatar
杜庆泉 已提交
333

杜庆泉's avatar
杜庆泉 已提交
334
				// 挨个通知,所有的监听器
杜庆泉's avatar
杜庆泉 已提交
335
				if(Global.onGetWifiListCallback != null){
杜庆泉's avatar
杜庆泉 已提交
336
					const data = new JSONObject();
杜庆泉's avatar
杜庆泉 已提交
337
					data["wifiList"] = Global.scanList
杜庆泉's avatar
杜庆泉 已提交
338
					Global.onGetWifiListCallback?.(data);
杜庆泉's avatar
杜庆泉 已提交
339
				}
杜庆泉's avatar
杜庆泉 已提交
340 341 342 343 344
				// for (let perCallback in Global.onGetWifiListCallback) {
				// 	const data = new JSONObject();
				// 	data["wifiList"] = Global.scanList
				// 	perCallback(data);
				// }
杜庆泉's avatar
杜庆泉 已提交
345

杜庆泉's avatar
杜庆泉 已提交
346
			}
杜庆泉's avatar
杜庆泉 已提交
347

杜庆泉's avatar
杜庆泉 已提交
348 349
		}
	}
杜庆泉's avatar
杜庆泉 已提交
350

杜庆泉's avatar
杜庆泉 已提交
351 352
}

353 354


杜庆泉's avatar
杜庆泉 已提交
355
/************************* 下面是对外提供的函数 *************************/
杜庆泉's avatar
杜庆泉 已提交
356 357 358 359
/**
 * start wifi是否正在扫描
 */
var startWifiScaning = false
杜庆泉's avatar
杜庆泉 已提交
360

杜庆泉's avatar
杜庆泉 已提交
361
/**
杜庆泉's avatar
杜庆泉 已提交
362 363
 * 开启wifi
 */
杜庆泉's avatar
杜庆泉 已提交
364
@Suppress("DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
365 366
export function startWifi(option : WifiOption) {

杜庆泉's avatar
杜庆泉 已提交
367 368 369
	// 需要先开启wifi,才能使用后续的功能
	let requestCode = 1001;
	let permissionWifi = arrayOf("android.permission.ACCESS_FINE_LOCATION");
杜庆泉's avatar
杜庆泉 已提交
370
	var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
371 372
		errCode: 12001,
		errMsg: "startWifi:premission loss",
杜庆泉's avatar
杜庆泉 已提交
373
		errSubject: "uni-startWifi"
杜庆泉's avatar
杜庆泉 已提交
374 375 376 377 378 379 380 381 382 383 384
	}
	// 检查权限
	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
杜庆泉 已提交
385
	
杜庆泉's avatar
杜庆泉 已提交
386
	// 具备了权限,继续前进
杜庆泉's avatar
杜庆泉 已提交
387
	let wifiManager : WifiManager =
杜庆泉's avatar
杜庆泉 已提交
388 389
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
	// 用户没有开启wifi 总开关
杜庆泉's avatar
杜庆泉 已提交
390
	if (!wifiManager.isWifiEnabled()) {
杜庆泉's avatar
杜庆泉 已提交
391 392 393
		// wifi 没开启
		result.errCode = 12005;
		result.errMsg = "wifi not turned on";
杜庆泉's avatar
杜庆泉 已提交
394

杜庆泉's avatar
杜庆泉 已提交
395 396 397 398 399
		option.fail?.(result);
		option.complete?.(result);
		return;
	}
	// 初始化wifi 状态广播监听,后续所有的api,均基于此
杜庆泉's avatar
杜庆泉 已提交
400 401 402 403 404 405 406 407
	if(Global.mReceiver != null){
		// 说明已经注册过了
		result.errCode = 0
		result.errMsg = "startWifi:ok"
		
		option.success?.(result)
		option.complete?.(result)
		return 
杜庆泉's avatar
杜庆泉 已提交
408
	}
杜庆泉's avatar
杜庆泉 已提交
409 410 411
	
	
	Global.mReceiver = new CustomBroadcastReceiver(wifiManager)
杜庆泉's avatar
杜庆泉 已提交
412 413 414 415 416 417 418

	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
杜庆泉 已提交
419

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

杜庆泉's avatar
杜庆泉 已提交
422
	/**
杜庆泉's avatar
杜庆泉 已提交
423 424 425 426 427
		* activity 被销毁时,取消注册
		*/
	UTSAndroid.onAppActivityDestroy(function () {

		if (Global.mReceiver != null) {
杜庆泉's avatar
杜庆泉 已提交
428 429
			UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
			Global.mReceiver = null
杜庆泉's avatar
杜庆泉 已提交
430

杜庆泉's avatar
杜庆泉 已提交
431
			Global.scanList = []
杜庆泉's avatar
杜庆泉 已提交
432
			Global.onGetWifiListCallback = null
杜庆泉's avatar
杜庆泉 已提交
433
			Global.onWifiConnectCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
434
			Global.onWifiConnectWithPartialInfoCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
435
		}
杜庆泉's avatar
杜庆泉 已提交
436

杜庆泉's avatar
杜庆泉 已提交
437
	});
杜庆泉's avatar
杜庆泉 已提交
438
	startWifiScaning = true
杜庆泉's avatar
杜庆泉 已提交
439 440
	// 开始扫描
	wifiManager.startScan()
杜庆泉's avatar
杜庆泉 已提交
441

杜庆泉's avatar
杜庆泉 已提交
442 443
	result.errCode = 0
	result.errMsg = "startWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
444

杜庆泉's avatar
杜庆泉 已提交
445 446 447 448 449
	option.success?.(result)
	option.complete?.(result)

}

杜庆泉's avatar
杜庆泉 已提交
450
/**
杜庆泉's avatar
杜庆泉 已提交
451 452
	* 获取wifi列表
	*/
453
@Suppress("DEPRECATION")
杜庆泉's avatar
杜庆泉 已提交
454 455 456
export function getWifiList(option : WifiOption) {

	var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
457 458
		errCode: 12000,
		errMsg: "getWifiList:fail:not invoke startWifi",
杜庆泉's avatar
杜庆泉 已提交
459
		errSubject: "uni-getWifiList"
杜庆泉's avatar
杜庆泉 已提交
460
	}
杜庆泉's avatar
杜庆泉 已提交
461

462 463 464 465
	if (Global.mReceiver == null) {
		// 还没调用startWifi 提示报错
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
466

467 468
		return
	}
杜庆泉's avatar
杜庆泉 已提交
469 470

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

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

杜庆泉's avatar
杜庆泉 已提交
474 475 476 477 478 479

	Global.supendGetWifiSuccess = option.success
	Global.supendGetWifiComplete = option.complete
	
	wifiManager.startScan()
	
杜庆泉's avatar
杜庆泉 已提交
480

杜庆泉's avatar
杜庆泉 已提交
481 482 483
}


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

杜庆泉's avatar
杜庆泉 已提交
485
/**
杜庆泉's avatar
杜庆泉 已提交
486 487 488
	* wifi 链接成功的回调注册
	*/
export function onWifiConnected(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
489 490 491
	Global.onWifiConnectCallbackList.push(callback)
}

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

杜庆泉's avatar
杜庆泉 已提交
493
export function onWifiConnectedWithPartialInfo(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
494 495 496 497
	Global.onWifiConnectWithPartialInfoCallbackList.push(callback)
}


杜庆泉's avatar
杜庆泉 已提交
498
/**
杜庆泉's avatar
杜庆泉 已提交
499 500 501 502 503 504 505 506 507
 * wifi 链接成功的回调取消注册
 */
export function offWifiConnected(callback? : UTSCallback) {
	
	if(callback == null){
		Global.onWifiConnectCallbackList = []
		return
	}
	
杜庆泉's avatar
杜庆泉 已提交
508
	let callbackIndex = Global.onWifiConnectCallbackList.indexOf(callback)
杜庆泉's avatar
杜庆泉 已提交
509
	if (callbackIndex >= 0) {
杜庆泉's avatar
杜庆泉 已提交
510
		Global.onWifiConnectCallbackList.splice(callbackIndex, 1);
杜庆泉's avatar
杜庆泉 已提交
511 512 513
	}
}

杜庆泉's avatar
杜庆泉 已提交
514 515 516 517 518 519 520 521 522 523
/**
 * 不具备详细信息的wifi 反注册
 */
export function offWifiConnectedWithPartialInfo(callback? : UTSCallback) {
	
	if(callback == null){
		Global.onWifiConnectWithPartialInfoCallbackList = []
		return
	}
	
杜庆泉's avatar
杜庆泉 已提交
524
	let callbackIndex = Global.onWifiConnectWithPartialInfoCallbackList.indexOf(callback)
杜庆泉's avatar
杜庆泉 已提交
525
	if (callbackIndex >= 0) {
杜庆泉's avatar
杜庆泉 已提交
526 527 528 529
		Global.onWifiConnectWithPartialInfoCallbackList.splice(callbackIndex, 1);
	}
}

杜庆泉's avatar
杜庆泉 已提交
530
/**
杜庆泉's avatar
杜庆泉 已提交
531 532 533
	* 注册Wifi列表的监听事件
	*/
export function onGetWifiList(callback : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
534
	Global.onGetWifiListCallback = callback
杜庆泉's avatar
杜庆泉 已提交
535
}
杜庆泉's avatar
杜庆泉 已提交
536

杜庆泉's avatar
杜庆泉 已提交
537
/**
杜庆泉's avatar
杜庆泉 已提交
538 539 540
 * 取消注册Wifi列表的监听事件
 */
export function offGetWifiList(callback? : UTSCallback) {
杜庆泉's avatar
杜庆泉 已提交
541
	Global.onGetWifiListCallback = null
杜庆泉's avatar
杜庆泉 已提交
542 543
}

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

/**
杜庆泉's avatar
杜庆泉 已提交
546 547 548 549
 * 真正执行wifi链接逻辑
 */
function realWifiConnect(option : WifiConnectOption,result : UniWifiResult){
	
杜庆泉's avatar
杜庆泉 已提交
550 551 552
	if (Global.mReceiver == null || Global.scanList.length < 1) {
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
553
		
杜庆泉's avatar
杜庆泉 已提交
554 555
		return
	}
杜庆泉's avatar
杜庆泉 已提交
556
	
杜庆泉's avatar
杜庆泉 已提交
557
	// 执行后续的逻辑
杜庆泉's avatar
杜庆泉 已提交
558
	let scanWifiInfo : AndroidUniWifiInfo | null = null
杜庆泉's avatar
杜庆泉 已提交
559 560 561 562 563
	for (let scanResult in Global.scanList) {
		if (scanResult.SSID.equals(option.SSID)) {
			scanWifiInfo = scanResult
		}
	}
杜庆泉's avatar
杜庆泉 已提交
564
	
杜庆泉's avatar
杜庆泉 已提交
565
	if (scanWifiInfo == null) {
杜庆泉's avatar
杜庆泉 已提交
566 567 568 569 570
		// 不在扫描列表中返回错误
		option.fail?.(result)
		option.complete?.(result)
		return
	}
杜庆泉's avatar
杜庆泉 已提交
571
	
杜庆泉's avatar
杜庆泉 已提交
572
	let wifiConfigration = wrapWifiConfiguration(scanWifiInfo.SSID, option.password, scanWifiInfo.securityType);
杜庆泉's avatar
杜庆泉 已提交
573
	wifiConfigration.BSSID = scanWifiInfo.BSSID
杜庆泉's avatar
杜庆泉 已提交
574
	let wifiManager : WifiManager =
575
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
杜庆泉's avatar
杜庆泉 已提交
576
	
577
	// 如果已经存在了指定wifi 配置,移除之
杜庆泉's avatar
杜庆泉 已提交
578
	let targetExistConfig : WifiConfiguration | null = null
杜庆泉's avatar
杜庆泉 已提交
579 580 581 582 583 584
	let existingConfigs = wifiManager.getConfiguredNetworks();
	for (let existingConfig in existingConfigs) {
		if (existingConfig.SSID.equals("\"" + option.SSID + "\"")) {
			targetExistConfig = existingConfig
		}
	}
杜庆泉's avatar
杜庆泉 已提交
585
	// 如果wifi已经保存了当前ssid的配置,可能是别的应用添加的。android系统要求,需要删除掉重新添加
杜庆泉's avatar
杜庆泉 已提交
586
	if (targetExistConfig != null) {
杜庆泉's avatar
杜庆泉 已提交
587
		let removeRet = wifiManager.removeNetwork(targetExistConfig.networkId);
杜庆泉's avatar
杜庆泉 已提交
588
		
杜庆泉's avatar
杜庆泉 已提交
589
		if (!removeRet) {
杜庆泉's avatar
杜庆泉 已提交
590 591 592 593 594 595 596 597 598 599 600 601
			
			// add since 2023-03-28,如果当前系统大于等于android10, 则明确当前系统不支持
			if(Build.VERSION.SDK_INT > 28){
				// 系统大于android 9
				result.errCode = 12001
				result.errMsg = "connectWifi:system not support"
			}else{
				// 移除之前的配置失败了,返回错误,需要用户手动取消保存一下
				result.errCode = 12013
				result.errMsg = "connectWifi:wifi config may be expired"
			}
			
杜庆泉's avatar
杜庆泉 已提交
602 603
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
604
	
杜庆泉's avatar
杜庆泉 已提交
605 606
			return
		}
杜庆泉's avatar
杜庆泉 已提交
607
	
杜庆泉's avatar
杜庆泉 已提交
608
	}
杜庆泉's avatar
杜庆泉 已提交
609
	
杜庆泉's avatar
杜庆泉 已提交
610
	let currentConnect = wifiManager.getConnectionInfo()
杜庆泉's avatar
杜庆泉 已提交
611 612 613
	if (currentConnect.networkId >= 0) {
		wifiManager.disableNetwork(currentConnect.networkId)
	} else {
杜庆泉's avatar
杜庆泉 已提交
614
		wifiManager.removeNetwork(currentConnect.networkId)
杜庆泉's avatar
杜庆泉 已提交
615
	}
杜庆泉's avatar
杜庆泉 已提交
616
	wifiManager.disconnect()
杜庆泉's avatar
杜庆泉 已提交
617
	
杜庆泉's avatar
杜庆泉 已提交
618
	let connected = false;
619
	try {
杜庆泉's avatar
杜庆泉 已提交
620
	
621
		let netID = wifiManager.addNetwork(wifiConfigration);
杜庆泉's avatar
杜庆泉 已提交
622
		// 如果-1 说明没添加上,报错即可
杜庆泉's avatar
杜庆泉 已提交
623
		if (netID < 0) {
杜庆泉's avatar
杜庆泉 已提交
624 625
			result.errCode = 12002
			result.errMsg = "connectWifi:password error Wi-Fi"
杜庆泉's avatar
杜庆泉 已提交
626
	
杜庆泉's avatar
杜庆泉 已提交
627 628
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
629
	
杜庆泉's avatar
杜庆泉 已提交
630 631
			return
		}
杜庆泉's avatar
杜庆泉 已提交
632 633
	
	
634
		let enabled = wifiManager.enableNetwork(netID, true);
杜庆泉's avatar
杜庆泉 已提交
635
		if (!enabled) {
杜庆泉's avatar
杜庆泉 已提交
636
	
杜庆泉's avatar
杜庆泉 已提交
637 638
			result.errCode = 12007
			result.errMsg = "connectWifi:user denied"
杜庆泉's avatar
杜庆泉 已提交
639
	
杜庆泉's avatar
杜庆泉 已提交
640 641
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
642
	
杜庆泉's avatar
杜庆泉 已提交
643 644
			return
		}
杜庆泉's avatar
杜庆泉 已提交
645
		connected = wifiManager.reconnect();
杜庆泉's avatar
杜庆泉 已提交
646
	
647
	} catch (e) {
杜庆泉's avatar
杜庆泉 已提交
648
		connected = false;
649 650
		console.log(e);
	}
杜庆泉's avatar
杜庆泉 已提交
651
	
杜庆泉's avatar
杜庆泉 已提交
652
	if (!connected) {
杜庆泉's avatar
杜庆泉 已提交
653
		// 出错了,返回错误
杜庆泉's avatar
杜庆泉 已提交
654 655 656
		// 兜底的报错
		result.errCode = 12010
		result.errMsg = "connectWifi:fail:unknown error"
杜庆泉's avatar
杜庆泉 已提交
657
	
杜庆泉's avatar
杜庆泉 已提交
658 659
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
660
		return
打打卡夫卡's avatar
打打卡夫卡 已提交
661
	}
杜庆泉's avatar
杜庆泉 已提交
662
	
杜庆泉's avatar
杜庆泉 已提交
663 664
	wifiManager.saveConfiguration()
	//scanWifiInfo 根据 partialInfo 填充给返回字段
杜庆泉's avatar
杜庆泉 已提交
665
	if (option.partialInfo != null && option.partialInfo == true) {
杜庆泉's avatar
杜庆泉 已提交
666
		let wifiPartialInfo : UniWifiInfo = {
杜庆泉's avatar
杜庆泉 已提交
667
			SSID: scanWifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
668
		}
杜庆泉's avatar
杜庆泉 已提交
669
		result.wifi = wifiPartialInfo
杜庆泉's avatar
杜庆泉 已提交
670 671
	} else {
		result.wifi = wrapUniWifiInfoFromAndroid(scanWifiInfo)
杜庆泉's avatar
杜庆泉 已提交
672
	}
杜庆泉's avatar
杜庆泉 已提交
673
	
杜庆泉's avatar
杜庆泉 已提交
674
	// result.wifi = scanWifiInfo.toUTSJSON(option.partialInfo)
打打卡夫卡's avatar
打打卡夫卡 已提交
675
	result.errCode = 0
杜庆泉's avatar
杜庆泉 已提交
676
	result.errMsg = "connectWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
677
	
杜庆泉's avatar
杜庆泉 已提交
678 679
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731
}

/**
 * 链接指定wifi
 */
@Suppress("UNUSED_PARAMETER", "DEPRECATION")
export function connectWifi(option : WifiConnectOption) {


	var result : UniWifiResult = {
		errCode: 12000,
		errMsg: "connectWifi:fail:not invoke startWifi",
		errSubject: "uni-connectWifi",
	}

	if (option.maunal == true) {
		// 指定了手动模式
		let manunalIntent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
		UTSAndroid.getUniActivity()!.startActivity(manunalIntent);

		result.errCode = 0
		result.errMsg = "connectWifi:ok"

		option.success?.(result)
		option.complete?.(result)
		return
	}

	
	
	// add since 2022-03-28 ,增加逻辑,如果正在扫描中,则可以等待5s
	if(startWifiScaning){
		let taskCount = 0
		let taskId:number  = 0
		taskId = setInterval(function(){
		
			taskCount += 1;
			if(taskCount >= 5 || startWifiScaning == false){
				// 超过10s了。或者扫描过程结束了
				clearInterval(taskId)
				realWifiConnect(option,result)
			}
		},2000)
		
		UTSAndroid.onAppActivityDestroy(function () {
			clearInterval(taskId)
		});
	}else{
		realWifiConnect(option,result)
	}

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

733 734
}

杜庆泉's avatar
杜庆泉 已提交
735 736

/**
杜庆泉's avatar
杜庆泉 已提交
737 738 739
	* 关闭wifi
	*/
export function stopWifi(option : WifiOption) {
杜庆泉's avatar
杜庆泉 已提交
740 741
	// 需要先开启wifi,才能使用后续的功能
	if (Global.mReceiver == null) {
杜庆泉's avatar
杜庆泉 已提交
742
		var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
743
			errCode: 12000,
杜庆泉's avatar
杜庆泉 已提交
744
			errSubject: "uni-stopWifi",
杜庆泉's avatar
杜庆泉 已提交
745
			errMsg: "stopWifi:not init"
杜庆泉's avatar
杜庆泉 已提交
746 747 748
		}
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
749 750

		return
杜庆泉's avatar
杜庆泉 已提交
751
	}
杜庆泉's avatar
杜庆泉 已提交
752
	try {
753
		UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
杜庆泉's avatar
杜庆泉 已提交
754
	} catch (e) {
755 756 757
		// 多次调用
		//TODO handle the exception
	}
杜庆泉's avatar
杜庆泉 已提交
758
	
杜庆泉's avatar
杜庆泉 已提交
759
	Global.onGetWifiListCallback = null
杜庆泉's avatar
杜庆泉 已提交
760 761
	Global.onWifiConnectWithPartialInfoCallbackList = []
	Global.onWifiConnectCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
762 763
	Global.mReceiver = null
	
杜庆泉's avatar
杜庆泉 已提交
764
	let result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
765
		errCode: 0,
杜庆泉's avatar
杜庆泉 已提交
766
		errSubject: "uni-stopWifi",
杜庆泉's avatar
杜庆泉 已提交
767
		errMsg: "stopWifi:ok"
768
	}
杜庆泉's avatar
杜庆泉 已提交
769 770
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
771

杜庆泉's avatar
杜庆泉 已提交
772 773 774
}

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

杜庆泉's avatar
杜庆泉 已提交
780 781
	let wifiInfo : UniWifiInfo = {
		SSID: ""
杜庆泉's avatar
杜庆泉 已提交
782
	}
打打卡夫卡's avatar
打打卡夫卡 已提交
783

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

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

795 796
		return
	}
杜庆泉's avatar
杜庆泉 已提交
797

杜庆泉's avatar
杜庆泉 已提交
798
	// 需要先校验权限,没有位置权限无法获取wifi
799
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
杜庆泉's avatar
杜庆泉 已提交
800
		// 尚不具备权限,返回错误
打打卡夫卡's avatar
打打卡夫卡 已提交
801 802
		res.errCode = 12001
		res.errMsg = "getConnectedWifi:permission loss"
杜庆泉's avatar
杜庆泉 已提交
803

杜庆泉's avatar
杜庆泉 已提交
804 805 806
		option.fail?.(res)
		option.complete?.(res)
		return;
杜庆泉's avatar
杜庆泉 已提交
807 808
	}

809
	const context = UTSAndroid.getAppContext();
810
	if (context != null) {
杜庆泉's avatar
杜庆泉 已提交
811 812 813
		const wm = context.getSystemService(
			Context.WIFI_SERVICE
		) as WifiManager;
杜庆泉's avatar
杜庆泉 已提交
814
		// 测试android 12上可以使用
打打卡夫卡's avatar
打打卡夫卡 已提交
815
		//@ts-ignore
杜庆泉's avatar
杜庆泉 已提交
816
		const winfo = wm.getConnectionInfo();
杜庆泉's avatar
杜庆泉 已提交
817 818

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

杜庆泉's avatar
杜庆泉 已提交
830 831 832 833
				option.fail?.(res)
				option.complete?.(res)
				return
			}
杜庆泉's avatar
杜庆泉 已提交
834
			res.wifi = wifiInfo;
杜庆泉's avatar
杜庆泉 已提交
835
		}
杜庆泉's avatar
杜庆泉 已提交
836

杜庆泉's avatar
杜庆泉 已提交
837 838
		res.errCode = 0
		res.errMsg = "getConnectedWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
839

杜庆泉's avatar
杜庆泉 已提交
840 841 842
		option.success?.(res)
		option.complete?.(res)
		return
843
	}
杜庆泉's avatar
杜庆泉 已提交
844 845
	option.fail?.(res)
	option.complete?.(res)
846
}