killapp/Assets/Scripts/UI/Pages/DeviceInfoPage/FirmwareUpdatePage.cs
“虞渠成” 715921b9f2 feat: 新增WiFi OTA推送功能,完善固件更新流程
1. 新增多服务器API地址配置
2. 添加OTA推送请求数据结构
3. 实现WiFi模式下直接推送OTA指令逻辑
4. 新增多语言提示文本
5. 补充BLE通信接口文档
6. 修复部分代码格式和跳转逻辑问题
2026-07-14 17:05:14 +08:00

241 lines
8.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Kill.Bluetooth;
using Kill.Core;
using Kill.Managers;
using Kill.Network;
using Kill.UI.Components;
using UnityEngine;
using UnityEngine.UI;
namespace Kill.UI.Pages
{
public class FirmwareUpdatePage : MonoBehaviour
{
public GameObject latestTip;
public GameObject getNewVersionTip;
public Text versionText;
public Text changeLogText;
public Button backButton;
public Button updateButton;
OTAData otaData;
void Start()
{
UIManager.Instance.RegisterBackAction(Back);
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(Back);
updateButton.onClick.RemoveAllListeners();
updateButton.onClick.AddListener(OnUpdateButtonClick);
updateButton.gameObject.SetActive(false);
GetOtaInfo();
}
public async void GetOtaInfo()
{
LoadingUI.Show();
var response = await NetworkCtrl.Instance.Get<OTAResponse>("/api/v1/ota/latest");
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
otaData = data.data;
Debug.Log($"加载OTA信息成功版本: {otaData.version}");
InitOtaUI();
},
onError:(code,message)=>
{
Debug.LogError($"加载OTA信息失败: {message}");
}
);
}
public void InitOtaUI()
{
string nowVersion = DataManager.Instance.selectedDevice.firmware_version;
string[] versionParts = otaData.version.Split('.');
string[] nowVersionParts = nowVersion.Split('.');
int nowversionNum = 0;
int versionNum = 0;
int index=1;
for(int i=nowVersionParts.Length-1;i>=0;i--)
{
nowversionNum += int.Parse(nowVersionParts[i]) * 10*index++;
}
index = 1;
for (int i = versionParts.Length - 1; i >= 0; i--)
{
versionNum += int.Parse(versionParts[i]) * 10 * index++;
}
Debug.Log($"当前版本: {nowVersion} ({nowversionNum}), 最新版本: {otaData.version} ({versionNum})");
bool hasNewVersion = versionNum > nowversionNum;
if(hasNewVersion)
{
latestTip.SetActive(false);
getNewVersionTip.SetActive(true);
changeLogText.gameObject.SetActive(true);
versionText=getNewVersionTip.transform.Find("value").GetComponent<Text>();
versionText.text = otaData.version;
changeLogText.text = otaData.release_notes;
updateButton.gameObject.SetActive(true);
}
else
{
latestTip.SetActive(true);
getNewVersionTip.SetActive(false);
updateButton.gameObject.SetActive(false);
changeLogText.gameObject.SetActive(false);
versionText = latestTip.transform.Find("value").GetComponent<Text>();
versionText.text = otaData.version;
}
}
public void Back()
{
UIManager.Instance.RegisterBackAction(GetComponentInParent<DeviceInfoPage>().Back);
Destroy(gameObject);
Screen.sleepTimeout = SleepTimeout.SystemSetting;
}
public async void OnUpdateButtonClick()
{
Screen.sleepTimeout = SleepTimeout.NeverSleep;
// WiFi 模式:直接 push OTA 指令,设备自行下载固件
if (DataManager.Instance.hasWifi)
{
var pushRequest = new OTAPushRequest
{
ble_mac = DataManager.Instance.selectedDevice.ble_mac,
version = otaData.version
};
var pushResponse = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/ota/push", pushRequest);
ResponseCodeHandler.HandleResponse(pushResponse,
onSuccess: (data) =>
{
ToastUI.Show("100308");
DataManager.Instance.selectedDevice.firmware_version = otaData.version;
},
onError: (code, message) =>
{
ToastUI.Show("100227");
Debug.LogError($"WiFi OTA push 失败: {message}");
}
);
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
return;
}
// BLE 模式:下载固件 → 校验 → 蓝牙传输
ToastUI.Show("100294");
UpdateLoadingUI.Instance.Show();
string savePath = Application.persistentDataPath + "/ota.bin";
var downloadResult = await NetworkCtrl.Instance.DownloadFile(otaData.download_url, savePath, UpdateLoadingUI.Instance.GetDownloadProcess);
UpdateLoadingUI.Instance.Hide();
if (!downloadResult.IsSuccess)
{
ToastUI.Show("100224");
return;
}
string md5 = NetworkCtrl.Instance.CalculateMD5(savePath);
if (md5 != otaData.md5)
{
ToastUI.Show("100223");
Debug.LogError("下载的文件MD5校验失败");
File.Delete(savePath);
return;
}
LoadFirmwareFile(savePath);
ToastUI.Show("100225");
UpdateLoadingUI.Instance.SetPrecent(0);
UpdateLoadingUI.Instance.Show();
uint firmwareVersion = ParseFirmwareVersion(otaData.version);
OTAManager.Instance.OnTransferProgress += OnOTATransferProgress;
StartCoroutine(OTAManager.Instance.PerformFullUpgrade(_selectedFirmwareData, firmwareVersion, (success) =>
{
Loom.QueueOnMainThread(() =>
{
if (success)
{
ToastUI.Show("100226");
DataManager.Instance.selectedDevice.firmware_version = otaData.version;
}
else
{
ToastUI.Show("100227");
}
UpdateLoadingUI.Instance.Hide();
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
});
}));
}
// 选中的固件文件数据
private byte[] _selectedFirmwareData;
private string _selectedFirmwarePath;
/// <summary>
/// 加载固件文件
/// </summary>
private void LoadFirmwareFile(string filePath)
{
try
{
// 获取文件大小
FileInfo fileInfo = new FileInfo(filePath);
long fileSize = fileInfo.Length;
// 读取文件
_selectedFirmwareData = File.ReadAllBytes(filePath);
_selectedFirmwarePath = filePath;
string fileName = Path.GetFileName(filePath);
}
catch (System.Exception)
{
ToastUI.Show("100224");
LoadingUI.Hide();
}
}
/// <summary>
/// 解析固件版本号
/// </summary>
private uint ParseFirmwareVersion(string version)
{
try
{
string[] parts = version.Split('.');
if (parts.Length >= 3 &&
uint.TryParse(parts[0], out uint major) &&
uint.TryParse(parts[1], out uint minor) &&
uint.TryParse(parts[2], out uint patch))
{
// 版本号格式:主版本.次版本.修订号 -> 32位整数
return (major << 16) | (minor << 8) | patch;
}
}
catch { }
// 默认返回版本号 1
return 1;
}
/// <summary>
/// OTA传输进度回调
/// </summary>
private void OnOTATransferProgress(int current, int total, int retryCount, int maxRetries)
{
UpdateLoadingUI.Instance.SetPrecent((float)current/ total);
}
}
}