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
			
			
杜庆泉's avatar
杜庆泉 已提交
311
			
杜庆泉's avatar
杜庆泉 已提交
312 313
			// wifi 扫描结果回调
			let results = this.mWifiManager!.scanResults;
杜庆泉's avatar
杜庆泉 已提交
314

杜庆泉's avatar
杜庆泉 已提交
315
			
杜庆泉's avatar
杜庆泉 已提交
316 317
			if (results != null) {
				Global.scanList = []
杜庆泉's avatar
杜庆泉 已提交
318 319 320
				for (let scanResult in results) {
					if (scanResult.SSID == null) {
						continue;
杜庆泉's avatar
杜庆泉 已提交
321
					}
杜庆泉's avatar
杜庆泉 已提交
322
					Global.scanList.push(wrapUniWifiInfoFromScan(scanResult));
杜庆泉's avatar
杜庆泉 已提交
323
				}
杜庆泉's avatar
杜庆泉 已提交
324

杜庆泉's avatar
杜庆泉 已提交
325
				// 挨个通知,所有的监听器
杜庆泉's avatar
杜庆泉 已提交
326
				if(Global.onGetWifiListCallback != null){
杜庆泉's avatar
杜庆泉 已提交
327
					const data = new JSONObject();
杜庆泉's avatar
杜庆泉 已提交
328
					data["wifiList"] = Global.scanList
杜庆泉's avatar
杜庆泉 已提交
329
					Global.onGetWifiListCallback?.(data);
330 331 332 333
					/**
					 * 确保onGetWifiList 只会被执行一次
					 */
					Global.onGetWifiListCallback = null
杜庆泉's avatar
杜庆泉 已提交
334
				}
杜庆泉's avatar
杜庆泉 已提交
335

杜庆泉's avatar
杜庆泉 已提交
336
			}
杜庆泉's avatar
杜庆泉 已提交
337

338 339 340 341 342 343 344 345 346 347 348 349 350
			let ret : UniWifiResult = {
				errCode: 0,
				errSubject: "uni-getWifiList",
				errMsg: "getWifiList:ok"
			}
			if(Global.supendGetWifiSuccess != null){
				Global.supendGetWifiSuccess?.(ret)
				Global.supendGetWifiSuccess = null
			}
			if(Global.supendGetWifiComplete != null){
				Global.supendGetWifiComplete?.(ret)
				Global.supendGetWifiComplete = null
			}
杜庆泉's avatar
杜庆泉 已提交
351 352
		}
	}
杜庆泉's avatar
杜庆泉 已提交
353

杜庆泉's avatar
杜庆泉 已提交
354 355
}

356 357


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

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

杜庆泉's avatar
杜庆泉 已提交
370 371 372
	// 需要先开启wifi,才能使用后续的功能
	let requestCode = 1001;
	let permissionWifi = arrayOf("android.permission.ACCESS_FINE_LOCATION");
杜庆泉's avatar
杜庆泉 已提交
373
	var result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
374 375
		errCode: 12001,
		errMsg: "startWifi:premission loss",
杜庆泉's avatar
杜庆泉 已提交
376
		errSubject: "uni-startWifi"
杜庆泉's avatar
杜庆泉 已提交
377 378 379 380
	}
	// 检查权限
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

杜庆泉's avatar
杜庆泉 已提交
381
		ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, permissionWifi, requestCode.toInt())
杜庆泉's avatar
杜庆泉 已提交
382 383 384 385 386 387
		// 尚不具备权限,返回错误
		option.fail?.(result)
		option.complete?.(result)

		return;
	}
杜庆泉's avatar
杜庆泉 已提交
388
	
杜庆泉's avatar
杜庆泉 已提交
389
	// 具备了权限,继续前进
杜庆泉's avatar
杜庆泉 已提交
390
	let wifiManager : WifiManager =
杜庆泉's avatar
杜庆泉 已提交
391 392
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
	// 用户没有开启wifi 总开关
杜庆泉's avatar
杜庆泉 已提交
393
	if (!wifiManager.isWifiEnabled()) {
杜庆泉's avatar
杜庆泉 已提交
394 395 396
		// wifi 没开启
		result.errCode = 12005;
		result.errMsg = "wifi not turned on";
杜庆泉's avatar
杜庆泉 已提交
397

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

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

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

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

		if (Global.mReceiver != null) {
杜庆泉's avatar
杜庆泉 已提交
431 432
			UTSAndroid.getUniActivity()!.unregisterReceiver(Global.mReceiver)
			Global.mReceiver = null
杜庆泉's avatar
杜庆泉 已提交
433

杜庆泉's avatar
杜庆泉 已提交
434
			Global.scanList = []
杜庆泉's avatar
杜庆泉 已提交
435
			Global.onGetWifiListCallback = null
杜庆泉's avatar
杜庆泉 已提交
436
			Global.onWifiConnectCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
437
			Global.onWifiConnectWithPartialInfoCallbackList = []
杜庆泉's avatar
杜庆泉 已提交
438
		}
杜庆泉's avatar
杜庆泉 已提交
439

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

杜庆泉's avatar
杜庆泉 已提交
445 446
	result.errCode = 0
	result.errMsg = "startWifi:ok"
杜庆泉's avatar
杜庆泉 已提交
447

杜庆泉's avatar
杜庆泉 已提交
448 449 450 451 452
	option.success?.(result)
	option.complete?.(result)

}

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

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

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

470 471
		return
	}
杜庆泉's avatar
杜庆泉 已提交
472 473

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

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

杜庆泉's avatar
杜庆泉 已提交
477 478 479 480 481 482

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

杜庆泉's avatar
杜庆泉 已提交
484 485 486
}


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

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

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

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


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

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

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

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

杜庆泉's avatar
杜庆泉 已提交
549 550

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

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

738 739
}

杜庆泉's avatar
杜庆泉 已提交
740 741

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

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

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

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

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

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

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

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

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

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

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
		if (option.partialInfo!= null) {
杜庆泉's avatar
杜庆泉 已提交
826
			let ret : UniWifiInfo = {
杜庆泉's avatar
杜庆泉 已提交
827
				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 852
}