index.uts 21.3 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
	}
	// 检查权限
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

378
		ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, permissionWifi, requestCode.toInt())
杜庆泉's avatar
杜庆泉 已提交
379 380 381 382 383 384
		// 尚不具备权限,返回错误
		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
	Global.supendGetWifiComplete = null
	Global.supendGetWifiSuccess = null
杜庆泉's avatar
杜庆泉 已提交
544 545
}

杜庆泉's avatar
杜庆泉 已提交
546 547

/**
杜庆泉's avatar
杜庆泉 已提交
548 549 550 551
 * 真正执行wifi链接逻辑
 */
function realWifiConnect(option : WifiConnectOption,result : UniWifiResult){
	
杜庆泉's avatar
杜庆泉 已提交
552 553 554
	if (Global.mReceiver == null || Global.scanList.length < 1) {
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
555
		
杜庆泉's avatar
杜庆泉 已提交
556 557
		return
	}
杜庆泉's avatar
杜庆泉 已提交
558
	
杜庆泉's avatar
杜庆泉 已提交
559
	// 执行后续的逻辑
杜庆泉's avatar
杜庆泉 已提交
560
	let scanWifiInfo : AndroidUniWifiInfo | null = null
杜庆泉's avatar
杜庆泉 已提交
561 562 563 564 565
	for (let scanResult in Global.scanList) {
		if (scanResult.SSID.equals(option.SSID)) {
			scanWifiInfo = scanResult
		}
	}
杜庆泉's avatar
杜庆泉 已提交
566
	
杜庆泉's avatar
杜庆泉 已提交
567
	if (scanWifiInfo == null) {
杜庆泉's avatar
杜庆泉 已提交
568 569 570 571 572
		// 不在扫描列表中返回错误
		option.fail?.(result)
		option.complete?.(result)
		return
	}
杜庆泉's avatar
杜庆泉 已提交
573
	
杜庆泉's avatar
杜庆泉 已提交
574
	let wifiConfigration = wrapWifiConfiguration(scanWifiInfo.SSID, option.password, scanWifiInfo.securityType);
杜庆泉's avatar
杜庆泉 已提交
575
	wifiConfigration.BSSID = scanWifiInfo.BSSID
杜庆泉's avatar
杜庆泉 已提交
576
	let wifiManager : WifiManager =
577
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
杜庆泉's avatar
杜庆泉 已提交
578
	
579
	// 如果已经存在了指定wifi 配置,移除之
杜庆泉's avatar
杜庆泉 已提交
580
	let targetExistConfig : WifiConfiguration | null = null
杜庆泉's avatar
杜庆泉 已提交
581 582 583 584 585 586
	let existingConfigs = wifiManager.getConfiguredNetworks();
	for (let existingConfig in existingConfigs) {
		if (existingConfig.SSID.equals("\"" + option.SSID + "\"")) {
			targetExistConfig = existingConfig
		}
	}
杜庆泉's avatar
杜庆泉 已提交
587
	// 如果wifi已经保存了当前ssid的配置,可能是别的应用添加的。android系统要求,需要删除掉重新添加
杜庆泉's avatar
杜庆泉 已提交
588
	if (targetExistConfig != null) {
杜庆泉's avatar
杜庆泉 已提交
589
		let removeRet = wifiManager.removeNetwork(targetExistConfig.networkId);
杜庆泉's avatar
杜庆泉 已提交
590
		
杜庆泉's avatar
杜庆泉 已提交
591
		if (!removeRet) {
杜庆泉's avatar
杜庆泉 已提交
592 593 594 595 596 597 598 599 600 601 602 603
			
			// 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
杜庆泉 已提交
604 605
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
606
	
杜庆泉's avatar
杜庆泉 已提交
607 608
			return
		}
杜庆泉's avatar
杜庆泉 已提交
609
	
杜庆泉's avatar
杜庆泉 已提交
610
	}
杜庆泉's avatar
杜庆泉 已提交
611
	
杜庆泉's avatar
杜庆泉 已提交
612
	let currentConnect = wifiManager.getConnectionInfo()
杜庆泉's avatar
杜庆泉 已提交
613 614 615
	if (currentConnect.networkId >= 0) {
		wifiManager.disableNetwork(currentConnect.networkId)
	} else {
杜庆泉's avatar
杜庆泉 已提交
616
		wifiManager.removeNetwork(currentConnect.networkId)
杜庆泉's avatar
杜庆泉 已提交
617
	}
杜庆泉's avatar
杜庆泉 已提交
618
	wifiManager.disconnect()
杜庆泉's avatar
杜庆泉 已提交
619
	
杜庆泉's avatar
杜庆泉 已提交
620
	let connected = false;
621
	try {
杜庆泉's avatar
杜庆泉 已提交
622
	
623
		let netID = wifiManager.addNetwork(wifiConfigration);
杜庆泉's avatar
杜庆泉 已提交
624
		// 如果-1 说明没添加上,报错即可
杜庆泉's avatar
杜庆泉 已提交
625
		if (netID < 0) {
杜庆泉's avatar
杜庆泉 已提交
626 627
			result.errCode = 12002
			result.errMsg = "connectWifi:password error Wi-Fi"
杜庆泉's avatar
杜庆泉 已提交
628
	
杜庆泉's avatar
杜庆泉 已提交
629 630
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
631
	
杜庆泉's avatar
杜庆泉 已提交
632 633
			return
		}
杜庆泉's avatar
杜庆泉 已提交
634 635
	
	
636
		let enabled = wifiManager.enableNetwork(netID, true);
杜庆泉's avatar
杜庆泉 已提交
637
		if (!enabled) {
杜庆泉's avatar
杜庆泉 已提交
638
	
杜庆泉's avatar
杜庆泉 已提交
639 640
			result.errCode = 12007
			result.errMsg = "connectWifi:user denied"
杜庆泉's avatar
杜庆泉 已提交
641
	
杜庆泉's avatar
杜庆泉 已提交
642 643
			option.fail?.(result)
			option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
644
	
杜庆泉's avatar
杜庆泉 已提交
645 646
			return
		}
杜庆泉's avatar
杜庆泉 已提交
647
		connected = wifiManager.reconnect();
杜庆泉's avatar
杜庆泉 已提交
648
	
649
	} catch (e) {
杜庆泉's avatar
杜庆泉 已提交
650
		connected = false;
651 652
		console.log(e);
	}
杜庆泉's avatar
杜庆泉 已提交
653
	
杜庆泉's avatar
杜庆泉 已提交
654
	if (!connected) {
杜庆泉's avatar
杜庆泉 已提交
655
		// 出错了,返回错误
杜庆泉's avatar
杜庆泉 已提交
656 657 658
		// 兜底的报错
		result.errCode = 12010
		result.errMsg = "connectWifi:fail:unknown error"
杜庆泉's avatar
杜庆泉 已提交
659
	
杜庆泉's avatar
杜庆泉 已提交
660 661
		option.fail?.(result)
		option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
662
		return
打打卡夫卡's avatar
打打卡夫卡 已提交
663
	}
杜庆泉's avatar
杜庆泉 已提交
664
	
杜庆泉's avatar
杜庆泉 已提交
665 666
	wifiManager.saveConfiguration()
	//scanWifiInfo 根据 partialInfo 填充给返回字段
杜庆泉's avatar
杜庆泉 已提交
667
	if (option.partialInfo != null && option.partialInfo == true) {
杜庆泉's avatar
杜庆泉 已提交
668
		let wifiPartialInfo : UniWifiInfo = {
杜庆泉's avatar
杜庆泉 已提交
669
			SSID: scanWifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
670
		}
杜庆泉's avatar
杜庆泉 已提交
671
		result.wifi = wifiPartialInfo
杜庆泉's avatar
杜庆泉 已提交
672 673
	} else {
		result.wifi = wrapUniWifiInfoFromAndroid(scanWifiInfo)
杜庆泉's avatar
杜庆泉 已提交
674
	}
杜庆泉's avatar
杜庆泉 已提交
675
	
杜庆泉's avatar
杜庆泉 已提交
676
	// result.wifi = scanWifiInfo.toUTSJSON(option.partialInfo)
打打卡夫卡's avatar
打打卡夫卡 已提交
677
	result.errCode = 0
杜庆泉's avatar
杜庆泉 已提交
678
	result.errMsg = "connectWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
679
	
杜庆泉's avatar
杜庆泉 已提交
680 681
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
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 732 733
}

/**
 * 链接指定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
杜庆泉 已提交
734

735 736
}

杜庆泉's avatar
杜庆泉 已提交
737 738

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

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

杜庆泉's avatar
杜庆泉 已提交
774 775 776
}

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

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

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

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

797 798
		return
	}
杜庆泉's avatar
杜庆泉 已提交
799

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

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

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

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

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

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

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