571 lines
18 KiB
C#
571 lines
18 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using Kill.Bluetooth;
|
||
using Kill.Core;
|
||
using Kill.Managers;
|
||
using Kill.Network;
|
||
using Kill.UI;
|
||
using Kill.UI.Components;
|
||
using Kill.UI.Pages;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class ConnectDevicePageCtrl : MonoBehaviour
|
||
{
|
||
/// <summary>
|
||
/// 0连接 1 失败 2 成功 3 选择wifi
|
||
/// </summary>
|
||
public GameObject[] sonPages;
|
||
public GameObject topBar;
|
||
public string blueToothNameKeyWord;
|
||
private List<BluetoothDevice> deviceList = new List<BluetoothDevice>();
|
||
public Button backButton;
|
||
public Button skipButton;
|
||
public GameObject titleText;
|
||
public GameObject scanningIcon;
|
||
void Start()
|
||
{
|
||
BluetoothManager.Instance.OnDeviceFound += OnDeviceFound;
|
||
BluetoothManager.Instance.OnConnectedSuccess += OnDeviceConnected;
|
||
BluetoothManager.Instance.OnConnectFailed += OnConnectFailed;
|
||
BluetoothManager.Instance.OnDisconnected += OnDeviceDisconnected;
|
||
EnterConnectPage();
|
||
}
|
||
void OnDestroy()
|
||
{
|
||
BluetoothManager.Instance.OnDeviceFound -= OnDeviceFound;
|
||
BluetoothManager.Instance.OnConnectedSuccess -= OnDeviceConnected;
|
||
BluetoothManager.Instance.OnConnectFailed -= OnConnectFailed;
|
||
BluetoothManager.Instance.OnDisconnected -= OnDeviceDisconnected;
|
||
}
|
||
IEnumerator WaitToScan()
|
||
{
|
||
yield return new WaitForSeconds(1);
|
||
EnterConnectPage();
|
||
}
|
||
public void EnterConnectPage()
|
||
{
|
||
if(BluetoothManager.Instance.IsConnected)
|
||
{
|
||
BluetoothManager.Instance.Disconnect();
|
||
StartCoroutine(WaitToScan());
|
||
}
|
||
OnStopScanClick();
|
||
BluetoothManager.Instance.ChangeAimMac("");
|
||
topBar.SetActive(true);
|
||
titleText.SetActive(false);
|
||
backButton.onClick.RemoveAllListeners();
|
||
backButton.onClick.AddListener(BackToHomePage);
|
||
backButton.gameObject.SetActive(true);
|
||
skipButton.gameObject.SetActive(false);
|
||
foreach(GameObject g in sonPages)
|
||
g.gameObject.SetActive(false);
|
||
sonPages[0].SetActive(true);
|
||
UIManager.Instance.RegisterBackAction(BackToHomePage);
|
||
OnScanClick();
|
||
}
|
||
public GameObject qrCodePlane;
|
||
public void ScanQrCode()
|
||
{
|
||
qrCodePlane.SetActive(true);
|
||
qrCodePlane.GetComponent<ScanQRcode>().OnQRCodeScanned+=GetQrResult;
|
||
}
|
||
public void GetQrResult(string result)
|
||
{
|
||
qrCodePlane.GetComponent<ScanQRcode>().Close();
|
||
foreach(var d in DataManager.Instance.OwnedDevices)
|
||
{
|
||
if (d.ble_mac == result)
|
||
{
|
||
ToastUI.Show("100287");
|
||
qrCodePlane.GetComponent<ScanQRcode>().OnQRCodeScanned += GetQrResult;
|
||
return;
|
||
}
|
||
}
|
||
foreach(var d in DataManager.Instance.SharedDevices)
|
||
{
|
||
if (d.ble_mac == result)
|
||
{
|
||
ToastUI.Show("100287");
|
||
qrCodePlane.GetComponent<ScanQRcode>().OnQRCodeScanned += GetQrResult;
|
||
return;
|
||
}
|
||
}
|
||
isconnecting=true;
|
||
// 根据 MAC 在已扫描到的设备列表中查找对应设备
|
||
// iOS: Address 是 UUID, MacFromBroadcast 是真实 MAC
|
||
// Android: Address 本身就是 MAC
|
||
string targetMac = result.ToUpper();
|
||
var foundDevice = BluetoothManager.Instance.DiscoveredDevices.Find(
|
||
d => d.GetEffectiveAddress().ToUpper() == targetMac
|
||
);
|
||
if (foundDevice != null)
|
||
{
|
||
// 找到设备,用正确的地址连接(iOS 用 UUID,Android 用 MAC)
|
||
BluetoothManager.Instance.Connect(foundDevice.Address);
|
||
}
|
||
else
|
||
{
|
||
// 未找到,设置 aimMac 让扫描到设备时自动连接
|
||
BluetoothManager.Instance.ChangeAimMac(result);
|
||
}
|
||
LoadingUI.Show();
|
||
qrCodePlane.SetActive(false);
|
||
nowDeviceMac=result;
|
||
}
|
||
|
||
string errorTip="";
|
||
private void ShowErrorPage()
|
||
{
|
||
if(BluetoothManager.Instance.IsConnected)
|
||
{
|
||
BluetoothManager.Instance.Disconnect();
|
||
}
|
||
topBar.SetActive(false);
|
||
foreach(GameObject g in sonPages)
|
||
g.gameObject.SetActive(false);
|
||
sonPages[1].SetActive(true);
|
||
Text errorText=sonPages[1].transform.Find("提示").GetComponent<Text>();
|
||
if(errorTip!="")
|
||
{
|
||
errorText.text=LanguageManager.Instance.GetLanguage(errorTip);
|
||
}
|
||
else
|
||
{
|
||
errorText.text=LanguageManager.Instance.GetLanguage("100069");
|
||
}
|
||
UIManager.Instance.RegisterBackAction(EnterConnectPage);
|
||
LoadingUI.Hide();
|
||
}
|
||
public InputField wifiNameInput;
|
||
public InputField wifiPasswordInput;
|
||
|
||
public void ShowWifiPage()
|
||
{
|
||
topBar.SetActive(true);
|
||
titleText.SetActive(true);
|
||
backButton.gameObject.SetActive(false);
|
||
UIManager.Instance.ClearBackAction();
|
||
skipButton.gameObject.SetActive(true);
|
||
foreach(GameObject g in sonPages)
|
||
g.gameObject.SetActive(false);
|
||
sonPages[3].SetActive(true);
|
||
|
||
// 获取当前 WiFi 名称
|
||
string wifiName = GetCurrentWiFiName();
|
||
wifiNameInput.text = wifiName ?? "";
|
||
wifiPasswordInput.text="";
|
||
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 确认配置 WiFi
|
||
/// </summary>
|
||
public void OnWifiConfirmClick()
|
||
{
|
||
string ssid = wifiNameInput.text.Trim();
|
||
string password = wifiPasswordInput.text;
|
||
|
||
if (string.IsNullOrEmpty(ssid))
|
||
{
|
||
ToastUI.Show("100082");
|
||
return;
|
||
}
|
||
|
||
// 创建 WiFi 配置
|
||
var wifiControl = new Kill.Bluetooth.Protocol.WIFIControl
|
||
{
|
||
Enable = true,
|
||
SSID = ssid,
|
||
Password = password
|
||
};
|
||
|
||
LoadingUI.Show();
|
||
|
||
// 发送 WiFi 配置到设备
|
||
BLECommunicationManager.Instance.WriteWIFIControl(wifiControl, (success) =>
|
||
{
|
||
Loom.QueueOnMainThread(() =>
|
||
{
|
||
LoadingUI.Hide();
|
||
if (success)
|
||
{
|
||
UnityEngine.Debug.Log("WiFi 配置成功");
|
||
DataManager.Instance.deviceConfig.wifi_enable = true;
|
||
DataManager.Instance.deviceConfig.wifi_ssid = ssid;
|
||
DataManager.Instance.deviceConfig.wifi_password = password;
|
||
DataManager.Instance.SyncDeviceConfigToServer();
|
||
ShowSuccessPage();
|
||
}
|
||
else
|
||
{
|
||
ToastUI.Show("100083");;
|
||
}
|
||
});
|
||
});
|
||
}
|
||
/// <summary>
|
||
/// 0不可点击 1可点击
|
||
/// </summary>
|
||
public GameObject[] wifiConfirmButtons;
|
||
public void CheckWifiNameAndPassword()
|
||
{
|
||
string ssid = wifiNameInput.text.Trim();
|
||
string password = wifiPasswordInput.text;
|
||
if(string.IsNullOrEmpty(ssid) || string.IsNullOrEmpty(password))
|
||
{
|
||
wifiConfirmButtons[0].SetActive(true);
|
||
wifiConfirmButtons[1].SetActive(false);
|
||
}
|
||
else
|
||
{
|
||
wifiConfirmButtons[0].SetActive(false);
|
||
wifiConfirmButtons[1].SetActive(true);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前连接的 WiFi 名称
|
||
/// </summary>
|
||
private string GetCurrentWiFiName()
|
||
{
|
||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||
try
|
||
{
|
||
using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
||
using (AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
|
||
using (AndroidJavaObject wifiManager = currentActivity.Call<AndroidJavaObject>("getSystemService", "wifi"))
|
||
{
|
||
if (wifiManager == null) return null;
|
||
|
||
using (AndroidJavaObject wifiInfo = wifiManager.Call<AndroidJavaObject>("getConnectionInfo"))
|
||
{
|
||
if (wifiInfo == null) return null;
|
||
|
||
string ssid = wifiInfo.Call<string>("getSSID");
|
||
if (!string.IsNullOrEmpty(ssid) && ssid != "<unknown ssid>")
|
||
{
|
||
return ssid.Trim('"');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogError($"获取 WiFi 名称失败: {ex.Message}");
|
||
}
|
||
return null;
|
||
#elif UNITY_IOS && !UNITY_EDITOR
|
||
// iOS 调用原生插件
|
||
return GetWiFiNameIOS();
|
||
#else
|
||
return "Editor_WiFi"; // 编辑器返回模拟值
|
||
#endif
|
||
}
|
||
|
||
#if UNITY_IOS && !UNITY_EDITOR
|
||
[System.Runtime.InteropServices.DllImport("__Internal")]
|
||
private static extern System.IntPtr GetWiFiSSID();
|
||
|
||
/// <summary>
|
||
/// iOS 获取 WiFi 名称
|
||
/// </summary>
|
||
private string GetWiFiNameIOS()
|
||
{
|
||
try
|
||
{
|
||
System.IntPtr ptr = GetWiFiSSID();
|
||
if (ptr == System.IntPtr.Zero)
|
||
{
|
||
return null;
|
||
}
|
||
string ssid = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr);
|
||
// 释放内存
|
||
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
|
||
return ssid;
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogError($"iOS 获取 WiFi 名称失败: {ex.Message}");
|
||
return null;
|
||
}
|
||
}
|
||
#endif
|
||
public void ShowSuccessPage()
|
||
{
|
||
topBar.SetActive(false);
|
||
foreach(GameObject g in sonPages)
|
||
g.gameObject.SetActive(false);
|
||
sonPages[2].SetActive(true);
|
||
UIManager.Instance.RegisterBackAction(EnterConnectPage);
|
||
}
|
||
private void OnDeviceFound(BluetoothDevice device)
|
||
{
|
||
if(string.IsNullOrEmpty(device.Name))
|
||
return;
|
||
Debug.Log($"[发现新设备] {device.Name} Address={device.Address} MAC={device.GetEffectiveAddress()} RSSI={device.Rssi} 广播数据(Hex)={BitConverter.ToString(device.info)}");
|
||
foreach(var d in DataManager.Instance.OwnedDevices)
|
||
{
|
||
if(d.ble_mac==device.GetEffectiveAddress())
|
||
return;
|
||
}
|
||
foreach(var d in DataManager.Instance.SharedDevices)
|
||
{
|
||
if(d.ble_mac==device.GetEffectiveAddress())
|
||
return;
|
||
}
|
||
AddOneDevice(device);
|
||
|
||
}
|
||
private void OnDeviceConnected()
|
||
{
|
||
if (selectedIndex >= 0 && selectedIndex < deviceObjects.Count)
|
||
{
|
||
deviceObjects[selectedIndex].transform.Find("状态").Find("loading").gameObject.SetActive(false);
|
||
deviceObjects[selectedIndex].transform.Find("状态").Find("成功").gameObject.SetActive(true);
|
||
}
|
||
// 延迟 500ms 再查询,确保 BLE 连接完全就绪
|
||
StartCoroutine(DelayedQueryRegistration());
|
||
isconnecting =false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 延迟查询注册状态
|
||
/// </summary>
|
||
private System.Collections.IEnumerator DelayedQueryRegistration()
|
||
{
|
||
yield return new WaitForSeconds(0.5f);
|
||
//OnQueryRegistrationClick();
|
||
BandDevice();
|
||
}
|
||
|
||
private void OnConnectFailed(string address)
|
||
{
|
||
if(!isconnecting)
|
||
return;
|
||
errorTip="100069";
|
||
ShowErrorPage();
|
||
isconnecting=false;
|
||
}
|
||
|
||
private void OnDeviceDisconnected(string address)
|
||
{
|
||
// UpdateStatus($"已断开连接: {address}");
|
||
// if (deviceStatusText != null)
|
||
// deviceStatusText.text = "未连接";
|
||
}
|
||
public List<GameObject> deviceObjects;
|
||
/// <summary>
|
||
/// 开始扫描
|
||
/// </summary>
|
||
public void OnScanClick()
|
||
{
|
||
scanningIcon.SetActive(true);
|
||
devicePrefab.SetActive(false);
|
||
if (BluetoothManager.Instance != null)
|
||
{
|
||
// 清空列表
|
||
deviceList.Clear();
|
||
if (deviceObjects != null && deviceObjects.Count > 0)
|
||
{
|
||
foreach (var item in deviceObjects)
|
||
{
|
||
Destroy(item);
|
||
}
|
||
deviceObjects.Clear();
|
||
}
|
||
deviceObjects = new List<GameObject>();
|
||
// 用户进入配网页面,强制初始化以触发蓝牙开启提示
|
||
BluetoothManager.Instance.ForceInitialize();
|
||
BluetoothManager.Instance.StartScan(999f); // 扫描999秒
|
||
}
|
||
}
|
||
public GameObject deviceListParent;
|
||
public GameObject devicePrefab;
|
||
public GameObject deviceListUi;
|
||
bool isconnecting=false;
|
||
public void AddOneDevice(BluetoothDevice device)
|
||
{
|
||
if (deviceList.Contains(device))
|
||
return;
|
||
if(!device.Name.Contains(blueToothNameKeyWord))
|
||
return;
|
||
if(!deviceListUi.activeSelf)
|
||
deviceListUi.SetActive(true);
|
||
deviceList.Add(device);
|
||
GameObject deviceObject = Instantiate(devicePrefab, deviceListParent.transform);
|
||
deviceObject.transform.Find("name").GetComponent<Text>().text=device.Name;
|
||
deviceObject.transform.Find("mac").GetComponent<Text>().text=device.GetEffectiveAddress();
|
||
deviceObject.SetActive(true);
|
||
deviceObjects.Add(deviceObject);
|
||
int index = deviceObjects.Count-1;
|
||
deviceObject.GetComponent<Button>().onClick.AddListener(() =>ClickOneDevice(index));
|
||
isconnecting=true;
|
||
}
|
||
int selectedIndex=-1;
|
||
string nowDeviceMac="";
|
||
public void ClickOneDevice(int index)
|
||
{
|
||
if (BluetoothManager.Instance == null) return;
|
||
OnStopScanClick();
|
||
selectedIndex = index;
|
||
if (selectedIndex >= 0 && selectedIndex < deviceList.Count)
|
||
{
|
||
var device = deviceList[selectedIndex];
|
||
Debug.Log("设备mac:"+device.GetEffectiveAddress());
|
||
nowDeviceMac=device.GetEffectiveAddress();
|
||
BluetoothManager.Instance.Connect(device.Address);
|
||
LoadingUI.Show();
|
||
deviceObjects[index].transform.Find("状态").Find("loading").gameObject.SetActive(true);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止扫描
|
||
/// </summary>
|
||
public void OnStopScanClick()
|
||
{
|
||
scanningIcon.SetActive(false);
|
||
if (BluetoothManager.Instance != null)
|
||
{
|
||
BluetoothManager.Instance.StopScan();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 查询设备注册状态
|
||
/// </summary>
|
||
private void OnQueryRegistrationClick()
|
||
{
|
||
|
||
BLECommunicationManager.Instance.QueryRegistrationStatus((success,status) =>
|
||
{
|
||
Loom.QueueOnMainThread(() =>
|
||
{
|
||
if (success)
|
||
{
|
||
bool IsRegistered = status.IsRegistered;
|
||
if (IsRegistered)
|
||
{
|
||
errorTip = "100070";
|
||
ShowErrorPage();
|
||
}
|
||
else
|
||
{
|
||
BandDevice();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
errorTip = "100069";
|
||
ShowErrorPage();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
/// <summary>
|
||
/// 注册设备
|
||
/// </summary>
|
||
private void OnRegisterDeviceClick()
|
||
{
|
||
|
||
string username = DataManager.Instance.userInfo.id;
|
||
|
||
|
||
BLECommunicationManager.Instance.RegisterDevice(username, (success, message) =>
|
||
{
|
||
Loom.QueueOnMainThread(() =>
|
||
{
|
||
LoadingUI.Hide();
|
||
ShowWifiPage();
|
||
DataManager.Instance.SavaSelectedDeviceMac(nowDeviceMac);
|
||
// if (success)
|
||
// {
|
||
// ShowWifiPage();
|
||
// DataManager.Instance.SavaSelectedDeviceMac(nowDeviceMac);
|
||
// }
|
||
// else
|
||
// {
|
||
// errorTip = "100070";
|
||
// ShowErrorPage();
|
||
// }
|
||
});
|
||
});
|
||
}
|
||
/// <summary>
|
||
/// 注销用户
|
||
/// </summary>
|
||
private void OnUnregisterUserClick()
|
||
{
|
||
string username = DataManager.Instance.userInfo.id;
|
||
BLECommunicationManager.Instance.UnregisterUser(username, (response) =>
|
||
{
|
||
Loom.QueueOnMainThread(() =>
|
||
{
|
||
if (response.IsSuccess)
|
||
{
|
||
Debug.Log($"用户 {username} 注销成功!");
|
||
}
|
||
else
|
||
{
|
||
OnUnregisterUserClick();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
public void BackToHomePage()
|
||
{
|
||
OnStopScanClick();
|
||
UIManager.Instance.OpenPage(UIManager.PageName.homePage, null, true);
|
||
}
|
||
/// <summary>
|
||
/// 绑定设备
|
||
/// </summary>
|
||
public async void BandDevice()
|
||
{
|
||
|
||
LoadingUI.Show();
|
||
try
|
||
{
|
||
BandDeviceRequest request = new BandDeviceRequest
|
||
{
|
||
device_sn = nowDeviceMac,
|
||
user_id = DataManager.Instance.userInfo.id,
|
||
};
|
||
|
||
Debug.Log($"绑定设备请求: deviceSn={request.device_sn}, userId={request.user_id}");
|
||
|
||
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/device/bind", request);
|
||
LoadingUI.Hide();
|
||
ResponseCodeHandler.HandleResponse(response,
|
||
onSuccess: (data) =>
|
||
{
|
||
Debug.Log($"绑定设备成功");
|
||
OnRegisterDeviceClick();
|
||
}
|
||
,
|
||
onError: (code,message) =>
|
||
{
|
||
Debug.Log($"绑定设备失败:{code},{message}");
|
||
errorTip = "100070";
|
||
ShowErrorPage();
|
||
}
|
||
);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LoadingUI.Hide();
|
||
Debug.LogError($"绑定设备异常: {ex.Message}");
|
||
}
|
||
}
|
||
public void ConnectError()
|
||
{
|
||
errorTip = "100069";
|
||
ShowErrorPage();
|
||
}
|
||
|
||
}
|