index.uts 21.5 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
 * 判断当前wifi的加密类型
 */
杜庆泉's avatar
杜庆泉 已提交
215 216 217 218 219 220 221 222 223
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 374
	
	let result : UniWifiResult = {
杜庆泉's avatar
杜庆泉 已提交
375 376
		errCode: 12001,
		errMsg: "startWifi:premission loss",
杜庆泉's avatar
杜庆泉 已提交
377
		errSubject: "uni-startWifi"
杜庆泉's avatar
杜庆泉 已提交
378
	}
杜庆泉's avatar
杜庆泉 已提交
379

杜庆泉's avatar
杜庆泉 已提交
380 381 382
	// 检查权限
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

杜庆泉's avatar
杜庆泉 已提交
383
		ActivityCompat.requestPermissions(UTSAndroid.getUniActivity()!, permissionWifi, requestCode.toInt())
杜庆泉's avatar
杜庆泉 已提交
384
		// 尚不具备权限,返回错误
杜庆泉's avatar
杜庆泉 已提交
385 386 387
		let err = new UniError("uni-startWifi",12001,"startWifi:premission loss");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
388 389 390

		return;
	}
杜庆泉's avatar
杜庆泉 已提交
391
	
杜庆泉's avatar
杜庆泉 已提交
392
	// 具备了权限,继续前进
杜庆泉's avatar
杜庆泉 已提交
393
	let wifiManager : WifiManager =
杜庆泉's avatar
杜庆泉 已提交
394 395
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
	// 用户没有开启wifi 总开关
杜庆泉's avatar
杜庆泉 已提交
396
	if (!wifiManager.isWifiEnabled()) {
杜庆泉's avatar
杜庆泉 已提交
397
		// wifi 没开启
杜庆泉's avatar
杜庆泉 已提交
398 399 400
		let err = new UniError("uni-startWifi",12005,"wifi not turned on");
		option.fail?.(err);
		option.complete?.(err);
杜庆泉's avatar
杜庆泉 已提交
401 402 403
		return;
	}
	// 初始化wifi 状态广播监听,后续所有的api,均基于此
杜庆泉's avatar
杜庆泉 已提交
404 405 406 407 408 409 410 411
	if(Global.mReceiver != null){
		// 说明已经注册过了
		result.errCode = 0
		result.errMsg = "startWifi:ok"
		
		option.success?.(result)
		option.complete?.(result)
		return 
杜庆泉's avatar
杜庆泉 已提交
412
	}
杜庆泉's avatar
杜庆泉 已提交
413 414 415
	
	
	Global.mReceiver = new CustomBroadcastReceiver(wifiManager)
杜庆泉's avatar
杜庆泉 已提交
416 417 418 419 420 421 422

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

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

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

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

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

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

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

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

}

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


461 462
	if (Global.mReceiver == null) {
		// 还没调用startWifi 提示报错
杜庆泉's avatar
杜庆泉 已提交
463 464 465 466
		let err = new UniError("uni-getWifiList",12000,"getWifiList:fail:not invoke startWifi");
		
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
467

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

/**
杜庆泉's avatar
杜庆泉 已提交
549 550
 * 真正执行wifi链接逻辑
 */
杜庆泉's avatar
杜庆泉 已提交
551
function realWifiConnect(option : WifiConnectOption){
杜庆泉's avatar
杜庆泉 已提交
552
	
杜庆泉's avatar
杜庆泉 已提交
553
	if (Global.mReceiver == null || Global.scanList.length < 1) {
杜庆泉's avatar
杜庆泉 已提交
554 555 556 557
		
		let err = new UniError("uni-connectWifi",12000,"connectWifi:fail:not invoke startWifi");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉'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
		// 不在扫描列表中返回错误
杜庆泉's avatar
杜庆泉 已提交
572 573 574
		let err = new UniError("uni-connectWifi",12000,"connectWifi:fail:not invoke startWifi");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
575 576
		return
	}
杜庆泉's avatar
杜庆泉 已提交
577
	
杜庆泉's avatar
杜庆泉 已提交
578
	let wifiConfigration = wrapWifiConfiguration(scanWifiInfo.SSID, option.password, scanWifiInfo.securityType);
杜庆泉's avatar
杜庆泉 已提交
579
	wifiConfigration.BSSID = scanWifiInfo.BSSID
杜庆泉's avatar
杜庆泉 已提交
580
	let wifiManager : WifiManager =
581
		UTSAndroid.getAppContext()!.getSystemService(Context.WIFI_SERVICE) as WifiManager
杜庆泉's avatar
杜庆泉 已提交
582
	
583
	// 如果已经存在了指定wifi 配置,移除之
杜庆泉's avatar
杜庆泉 已提交
584
	let targetExistConfig : WifiConfiguration | null = null
杜庆泉's avatar
杜庆泉 已提交
585 586 587 588 589 590
	let existingConfigs = wifiManager.getConfiguredNetworks();
	for (let existingConfig in existingConfigs) {
		if (existingConfig.SSID.equals("\"" + option.SSID + "\"")) {
			targetExistConfig = existingConfig
		}
	}
杜庆泉's avatar
杜庆泉 已提交
591
	// 如果wifi已经保存了当前ssid的配置,可能是别的应用添加的。android系统要求,需要删除掉重新添加
杜庆泉's avatar
杜庆泉 已提交
592
	if (targetExistConfig != null) {
杜庆泉's avatar
杜庆泉 已提交
593
		let removeRet = wifiManager.removeNetwork(targetExistConfig.networkId);
杜庆泉's avatar
杜庆泉 已提交
594
		
杜庆泉's avatar
杜庆泉 已提交
595
		if (!removeRet) {
杜庆泉's avatar
杜庆泉 已提交
596 597 598 599
			
			// add since 2023-03-28,如果当前系统大于等于android10, 则明确当前系统不支持
			if(Build.VERSION.SDK_INT > 28){
				// 系统大于android 9
杜庆泉's avatar
杜庆泉 已提交
600 601 602
				let err = new UniError("uni-connectWifi",12001,"connectWifi:system not support");
				option.fail?.(err)
				option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
603 604
			}else{
				// 移除之前的配置失败了,返回错误,需要用户手动取消保存一下
杜庆泉's avatar
杜庆泉 已提交
605 606 607
				let err = new UniError("uni-connectWifi",12013,"connectWifi:wifi config may be expired");
				option.fail?.(err)
				option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
608 609 610
			}
			
	
杜庆泉's avatar
杜庆泉 已提交
611 612
			return
		}
杜庆泉's avatar
杜庆泉 已提交
613
	
杜庆泉's avatar
杜庆泉 已提交
614
	}
杜庆泉's avatar
杜庆泉 已提交
615
	
杜庆泉's avatar
杜庆泉 已提交
616
	let currentConnect = wifiManager.getConnectionInfo()
杜庆泉's avatar
杜庆泉 已提交
617 618 619
	if (currentConnect.networkId >= 0) {
		wifiManager.disableNetwork(currentConnect.networkId)
	} else {
杜庆泉's avatar
杜庆泉 已提交
620
		wifiManager.removeNetwork(currentConnect.networkId)
杜庆泉's avatar
杜庆泉 已提交
621
	}
杜庆泉's avatar
杜庆泉 已提交
622
	wifiManager.disconnect()
杜庆泉's avatar
杜庆泉 已提交
623
	
杜庆泉's avatar
杜庆泉 已提交
624
	let connected = false;
625
	try {
杜庆泉's avatar
杜庆泉 已提交
626
	
627
		let netID = wifiManager.addNetwork(wifiConfigration);
杜庆泉's avatar
杜庆泉 已提交
628
		// 如果-1 说明没添加上,报错即可
杜庆泉's avatar
杜庆泉 已提交
629
		if (netID < 0) {
杜庆泉's avatar
杜庆泉 已提交
630 631
			
			let err = new UniError("uni-connectWifi",12002,"connectWifi:password error Wi-Fi");
杜庆泉's avatar
杜庆泉 已提交
632
	
杜庆泉's avatar
杜庆泉 已提交
633 634
			option.fail?.(err)
			option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
635
	
杜庆泉's avatar
杜庆泉 已提交
636 637
			return
		}
杜庆泉's avatar
杜庆泉 已提交
638 639
	
	
640
		let enabled = wifiManager.enableNetwork(netID, true);
杜庆泉's avatar
杜庆泉 已提交
641
		if (!enabled) {
杜庆泉's avatar
杜庆泉 已提交
642
	
杜庆泉's avatar
杜庆泉 已提交
643 644 645 646
			let err = new UniError("uni-connectWifi",12007,"connectWifi:user denied");
				
			option.fail?.(err)
			option.complete?.(err)
杜庆泉'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
		// 兜底的报错
杜庆泉's avatar
杜庆泉 已提交
660 661 662
		let err = new UniError("uni-connectWifi",12010,"connectWifi:fail:unknown error");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
663
		return
打打卡夫卡's avatar
打打卡夫卡 已提交
664
	}
杜庆泉's avatar
杜庆泉 已提交
665
	
杜庆泉's avatar
杜庆泉 已提交
666 667 668 669 670 671
	let result : UniWifiResult = {
		errCode: 0,
		errMsg: "connectWifi:ok",
		errSubject: "uni-connectWifi",
	}
	
杜庆泉's avatar
杜庆泉 已提交
672 673
	wifiManager.saveConfiguration()
	//scanWifiInfo 根据 partialInfo 填充给返回字段
杜庆泉's avatar
杜庆泉 已提交
674
	if (option.partialInfo != null && option.partialInfo == true) {
杜庆泉's avatar
杜庆泉 已提交
675
		let wifiPartialInfo : UniWifiInfo = {
杜庆泉's avatar
杜庆泉 已提交
676
			SSID: scanWifiInfo.SSID
杜庆泉's avatar
杜庆泉 已提交
677
		}
杜庆泉's avatar
杜庆泉 已提交
678
		result.wifi = wifiPartialInfo
杜庆泉's avatar
杜庆泉 已提交
679 680
	} else {
		result.wifi = wrapUniWifiInfoFromAndroid(scanWifiInfo)
杜庆泉's avatar
杜庆泉 已提交
681
	}
杜庆泉's avatar
杜庆泉 已提交
682 683
	
	
杜庆泉's avatar
杜庆泉 已提交
684 685
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
686 687 688 689 690 691 692 693 694 695 696 697 698
}

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

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

杜庆泉's avatar
杜庆泉 已提交
699 700 701 702 703
		let result : UniWifiResult = {
			errCode: 0,
			errMsg: "connectWifi:ok",
			errSubject: "uni-connectWifi",
		}
杜庆泉's avatar
杜庆泉 已提交
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721

		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)
杜庆泉's avatar
杜庆泉 已提交
722
				realWifiConnect(option)
杜庆泉's avatar
杜庆泉 已提交
723 724 725 726 727 728 729
			}
		},2000)
		
		UTSAndroid.onAppActivityDestroy(function () {
			clearInterval(taskId)
		});
	}else{
杜庆泉's avatar
杜庆泉 已提交
730
		realWifiConnect(option)
杜庆泉's avatar
杜庆泉 已提交
731 732 733
	}

	
杜庆泉'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 745 746
		let err = new UniError("uni-stopWifi",12000,"stopWifi:not init");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
747 748

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

杜庆泉's avatar
杜庆泉 已提交
768 769
	option.success?.(result)
	option.complete?.(result)
杜庆泉's avatar
杜庆泉 已提交
770

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

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

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

杜庆泉's avatar
杜庆泉 已提交
783
	
784
	if (Global.mReceiver == null) {
打打卡夫卡's avatar
打打卡夫卡 已提交
785
		// 还没调用startWifi 提示报错
杜庆泉's avatar
杜庆泉 已提交
786 787 788
		let err = new UniError("uni-getConnectedWifi",12000,"getConnectedWifi:fail:not invoke startWifi");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
789

790 791
		return
	}
杜庆泉's avatar
杜庆泉 已提交
792

杜庆泉's avatar
杜庆泉 已提交
793
	// 需要先校验权限,没有位置权限无法获取wifi
794
	if (ActivityCompat.checkSelfPermission(UTSAndroid.getUniActivity()!, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
杜庆泉's avatar
杜庆泉 已提交
795
		// 尚不具备权限,返回错误
杜庆泉's avatar
杜庆泉 已提交
796 797 798
		let err = new UniError("uni-getConnectedWifi",12001,"getConnectedWifi:permission loss");
		option.fail?.(err)
		option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
799
		return;
杜庆泉's avatar
杜庆泉 已提交
800 801
	}

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

		wifiInfo = wrapUniWifiInfoFromConnectInfo(winfo);
杜庆泉's avatar
杜庆泉 已提交
814 815 816 817 818 819 820
		
		let res : UniWifiResult = {
			errCode: 0,
			errMsg: "getConnectedWifi:ok",
			errSubject: "uni-getConnectedWifi",
		}

杜庆泉's avatar
杜庆泉 已提交
821
		// 判断一下是否wifi 关闭了
杜庆泉's avatar
杜庆泉 已提交
822
		if (option.partialInfo!= null) {
杜庆泉'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 831
				let err = new UniError("uni-getConnectedWifi",12005,"getConnectedWifi:fail:wifi is disable");
				option.fail?.(err)
				option.complete?.(err)
杜庆泉's avatar
杜庆泉 已提交
832 833
				return
			}
杜庆泉's avatar
杜庆泉 已提交
834
			res.wifi = wifiInfo;
杜庆泉's avatar
杜庆泉 已提交
835
		}
杜庆泉's avatar
杜庆泉 已提交
836 837


杜庆泉's avatar
杜庆泉 已提交
838 839 840
		option.success?.(res)
		option.complete?.(res)
		return
841
	}
杜庆泉's avatar
杜庆泉 已提交
842 843 844 845
	
	let err = new UniError("uni-getConnectedWifi",12000,"getConnectedWifi:fail:not invoke startWifi");
	option.fail?.(err)
	option.complete?.(err)
846 847
}