尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Android 平台 MAUI 应用更新服务

Android 平台 MAUI 应用更新服务
📅 发布时间:2026/6/19 23:51:38

该代码是面向 Android 平台 的 MAUI(.NET Multi-platform App UI)应用更新服务实现,实现了IUpgradeService接口,核心功能涵盖版本检查、APK 下载与安装,整体设计兼顾异常处理、用户体验与 Android 版本兼容性。

一、添加 IUpgradeService.cs 接口

/// <summary>/// 升级服务接口类/// </summary>public interface IUpgradeService{/// <summary>/// 检查更新/// </summary>/// <param name="latestVersion">最新版本</param>/// <returns></returns>bool CheckUpdatesAsync(string latestVersion);/// <summary>/// 下载安装文件/// </summary>/// <param name="url">下载URL</param>/// <param name="action">进度条处理方法</param>/// <returns></returns>Task DownloadFileAsync(string url, Action<long, long> action, CancellationToken cancellationToken = default);/// <summary>/// 安装APK的方法/// </summary>void InstallNewVersion();}

二、在 Platforms/Android 目录下创建 UpgradeService.cs 文件,实现 IUpgradeService 接口

 public class UpgradeService : IUpgradeService{readonly HttpClient _client;public UpgradeService(){_client = new HttpClient();}/// <summary>/// 检查当前应用版本是否需要更新/// </summary>/// <param name="latestVersion">服务器提供的最新版本号字符串(如 "1.2.3")</param>/// <returns>true表示需要更新,false表示不需要或版本相同</returns>public bool CheckUpdatesAsync(string latestVersion){try{// 获取当前版本(MAUI 6+ 推荐方式)var currentVersionStr = VersionTracking.Default.CurrentVersion;// 使用Version类进行专业比较var current = ParseVersion(currentVersionStr);var latest = ParseVersion(latestVersion);return latest > current;}catch{// 出现任何异常时保守返回true(建议更新)return true;}}/// <summary>/// 安全解析版本字符串(支持不同长度和格式)/// </summary>private Version ParseVersion(string versionStr){// 处理可能的null/emptyif (string.IsNullOrWhiteSpace(versionStr))return new Version(0, 0);// 分割版本号组成部分var parts = versionStr.Split('.').Select(p => int.TryParse(p, out int num) ? num : 0).ToArray();// 根据长度创建Version对象return parts.Length switch{1 => new Version(parts[0], 0),2 => new Version(parts[0], parts[1]),3 => new Version(parts[0], parts[1], parts[2]),4 => new Version(parts[0], parts[1], parts[2], parts[3]),_ => new Version(0, 0)};}/// <summary>/// 下载并安装APK/// </summary>/// <param name="url"></param>/// <param name="progressAction"></param>/// <param name="cancellationToken"></param>/// <returns></returns>/// <exception cref="ArgumentNullException"></exception>public async Task DownloadFileAsync(string url, Action<long, long> progressAction, CancellationToken cancellationToken = default){// 验证输入参数if (string.IsNullOrEmpty(url))throw new ArgumentNullException(nameof(url));if (progressAction == null)throw new ArgumentNullException(nameof(progressAction));// 生成唯一的临时文件名,避免冲突var fileName = "com.jiajing.iotplatform.apk";var tempFilePath = Path.Combine(FileSystem.AppDataDirectory, $"{fileName}.tmp");var finalFilePath = Path.Combine(FileSystem.AppDataDirectory, fileName);try{// 使用using确保HttpClient正确释放(如果不是全局单例的话)using var request = new HttpRequestMessage(HttpMethod.Get, url);// 异步获取响应,支持取消操作using var response = await _client.SendAsync(request,HttpCompletionOption.ResponseHeadersRead,cancellationToken);// 确保请求成功response.EnsureSuccessStatusCode();// 获取文件总大小,处理可能为null的情况var totalLength = response.Content.Headers.ContentLength ?? -1;var downloadedLength = 0L;// 读取响应流并写入文件using var stream = await response.Content.ReadAsStreamAsync(cancellationToken);await using var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);var buffer = new byte[8192]; // 使用8KB缓冲区(更适合大多数场景)int bytesRead;// 循环读取流,支持取消操作while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0){// 写入文件await fileStream.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);// 更新进度downloadedLength += bytesRead;progressAction(downloadedLength, totalLength);}// 确保所有数据都写入磁盘await fileStream.FlushAsync(cancellationToken).ConfigureAwait(false);// 下载完成后重命名临时文件(避免部分下载的文件被误认)if (File.Exists(finalFilePath))File.Delete(finalFilePath);File.Move(tempFilePath, finalFilePath);}catch (Exception){// 处理其他异常if (File.Exists(tempFilePath))File.Delete(tempFilePath);throw;}}/// <summary>/// 安装新版本/// </summary>public void InstallNewVersion(){var file = $"{FileSystem.AppDataDirectory}/{"com.jiajing.iotplatform.apk"}";var apkFile = new Java.IO.File(file);var intent = new Intent(Intent.ActionView);// 判断Android版本if (Build.VERSION.SdkInt >= BuildVersionCodes.N){//给临时读取权限intent.SetFlags(ActivityFlags.GrantReadUriPermission);var uri = FileProvider.GetUriForFile(AndroidApp.Application.Context, "com.jiajing.iotplatform.fileprovider", apkFile);// 设置显式 MIME 数据类型intent.SetDataAndType(uri, "application/vnd.android.package-archive");}else{intent.SetDataAndType(AndroidNet.Uri.FromFile(new Java.IO.File(file)), "application/vnd.android.package-archive");}//指定以新任务的方式启动Activityintent.AddFlags(ActivityFlags.NewTask);//激活一个新的ActivityAndroidApp.Application.Context.StartActivity(intent);}}

三、修改 MauiProgram.cs 文件,注册升级服务

#if ANDROID 是必不可少的,该条件编译指令能确保相关逻辑只在 Android 环境中执行.

    
public static class MauiProgram
{public static MauiApp CreateMauiApp(){ #if ANDROID    // Android 添加自定义升级服务builder.Services.AddSingleton<IUpgradeService, Platforms.Android.UpgradeService>();#endif } 
}

四、添加检查更新方法

Razor页面
    <!--版本更新弹框--><Modal Title="检测到新版本,是否更新?"@bind-Visible="@UpdateConfirm"Closable="false"Centered="true"OnOk="@OnConfirmUpdateAsync"><Space>【版本】: V @AppVersion.Version</Space><Space>【内容】:@AppVersion.ReleaseNotes</Space></Modal><!--下载进度弹框--><Modal Title="正在更新,请稍后..."@bind-Visible="@UpdateDialog"Closable="false" MaskClosable="false"Centered="true"Footer=null><Space>下载进度: @BytesReceived KB / @TotalBytesToReceive KB </Space><AntDesign.Progress StrokeWidth="20" Percent="@Percent" /></Modal>
Razor页面
/// <summary>
/// 最新版本信息
/// </summary>
public AppVersionInfo AppVersion = new();/// <summary>
/// 进度百分比
/// </summary>
public int Percent { get; set; }/// <summary>
/// 总字节数
/// </summary>
public long TotalBytesToReceive { get; set; }/// <summary>
///  已下载字节数
/// </summary>
public long BytesReceived { get; set; }/// <summary>
/// 是否显示进度框
/// </summary>
public bool UpdateDialog;/// <summary>
/// 升级提示并确认框
/// </summary>
public bool UpdateConfirm;/// <summary>
/// 检查是否软件是否为最新版本
/// </summary>
/// <returns></returns>
public async Task GetVersionNew()
{try{// 数据服务:调用编辑服务var response = await VersionService.GetVersionAsync();if (response != null && response.Code == ApiCode.Success){AppVersion = response.Data;// 检查是否为最新版本,非最新版本则提示更新if (UpgradeService.CheckUpdatesAsync(AppVersion.Version)){UpdateConfirm = true;}}}catch (Exception e){await dialogService.ErrorSnackbarAsync($"读取最新版本报错:{e.Message}");}
}/// <summary>
/// 下载新版本并安装
/// </summary>
/// <returns></returns>
public async Task OnConfirmUpdateAsync()
{try{// 启动版本升级 UpdateDialog = true;// 下载文件await UpgradeService.DownloadFileAsync(AppVersion.DownloadUrl, DownloadProgressChanged);// 安装新版本UpgradeService.InstallNewVersion();}catch (Exception e){await dialogService.ErrorSnackbarAsync($"下载新版本及安装时报错:{e.Message}");}finally{UpdateDialog = false;}
}/// <summary>
/// 下载进度
/// </summary>
/// <param name="readLength"></param>
/// <param name="allLength"></param>
private void DownloadProgressChanged(long readLength, long allLength)
{InvokeAsync(() =>{var c = (int)(readLength * 100 / allLength);// 刷新进度为每5%更新一次if (c > 0 && c % 5 == 0){Percent = c; //下载完成百分比BytesReceived = readLength / 1024; //当前已经下载的KbTotalBytesToReceive = allLength / 1024; //文件总大小KbStateHasChanged();}});
}#endregion

五、效果图

image image

相关新闻

  • SQL脚本:查询指定SQL的统计信息(cursor,awr)
  • 本地(或自下载)浏览器插件 安装指南
  • 路由查看命令

最新新闻

  • ComfyUI-KJNodes:5步掌握AI工作流效率跃升的核心技术
  • 如何安装BlockParty广告拦截器?iOS与macOS平台的快速上手教程
  • CANN/asc-devkit SIMD bfloat16转fp4x2函数
  • Git状态可视化:深入解析Nicolas Gallagher dotfiles的bash提示符系统
  • TPM架构探秘(三):从可信根到主动免疫——TPM 2.0架构下的可信平台构建实践
  • 为什么选择vscode-remote-try-node?Node.js开发容器的10大优势与实际应用案例

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号