MAUI项目在Android平台通过U盘实现软件更新

https://www.cnblogs.com/sesametech-dotnet/p/19674963

 

需求

项目使用MAUI开发的用Android工控机进行相关功能的实现。作为操作设备的屏幕嵌入到仪器中,要使用串口操作实现对仪器的控制。想要实现在有软件更新时,可以通过U盘实现对软件的升级。

功能实现

这里需要使用到 FileProvider,在Android 7之后出于安全考虑不再支持content://URL 或file:///URL这种文件访问方式。在Platforms/Android中主要添加/修改下面两个文件:

  • file_paths.xml
  • AndroidMainfest.xml

image

Platforms/Android/Resources下面新建xml文件夹,并添加 provider_paths.xml文件。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="root" path="" />
<files-path name="files" path="" />
<cache-path name="cache" path="" />
<external-path name="camera_photos" path="" />
<external-files-path name="external_file_path" path="" />
<external-cache-path name="external_cache_path" path="" />
</paths>

修改Platforms/Android下面的AndroidManifest.xml文件,在application下添加provider,再添加一个安卓安装的权限

  • REQUEST_INSTALL_PACKAGES(安装应用)
  • WRITE_EXTERNAL_STORAGE(写入外部存储中的文件)
  • READ_EXTERNAL_STORAGE(读取外部存储中的文件)

AndroidManifest.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.companyname.mauiupdateapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
</manifest>

在MainPage页面添加一个按钮用于实现软件安装功能,简化了项目实现,没有采用MVVM模式,直接通过Clicked事件实现软件安装。

<Button
x:Name="UpdateBtn"
Clicked="OnCheckUpdateClicked"
HorizontalOptions="Fill"
Text="安装Apk" />

按钮事件实现:

private async void OnCheckUpdateClicked(object? sender, EventArgs e)
{
await CheckForUpdates();
}
 
private async Task CheckForUpdates()
{
try
{
UpdateBtn.IsEnabled = false;
await _updateService.InstallUpdateAsync();
}
catch (Exception ex)
{
await DisplayAlertAsync("错误", $"异常: {ex.Message}", "确定");
}
finally
{
UpdateBtn.IsEnabled = true;
}
}

更新服务实现:

public class UpdateService
{
public async Task InstallUpdateAsync()
{
// 调用平台特定的更新逻辑
await UpdateHandlerFactory.Create().InstallUpdateAsync();
}
}
 
 
public interface IUpdateHandler
{
Task InstallUpdateAsync();
}
 
public static class UpdateHandlerFactory
{
public static IUpdateHandler Create()
{
#if ANDROID
return new MauiUpdateApp.Platforms.Android.UpdateHandler();
#else
return new DefaultUpdateHandler();
#endif
}
}
 
public class DefaultUpdateHandler : IUpdateHandler
{
public async Task InstallUpdateAsync()
{
// 默认实现,非 Android 平台使用
if (App.Current?.MainPage != null)
{
await App.Current.MainPage.DisplayAlertAsync("更新", "此平台不支持自动更新", "确定");
}
}
}

实现Android平台的安装Apk功能:

using Android.Content;
using MauiUpdateApp.Services;
using Android.App;
namespace MauiUpdateApp.Platforms.Android;
public class UpdateHandler : IUpdateHandler
{
private static readonly HttpClient client = new HttpClient();
 
public async Task InstallUpdateAsync()
{
try
{
var activity = Platform.CurrentActivity;
if (activity == null)
{
if (App.Current?.MainPage != null)
{
await App.Current.MainPage.DisplayAlertAsync("错误", "无法获取当前活动", "确定");
}
return;
}
 
PickOptions options = new() { PickerTitle = "Please select a comic file", };
var results = await FilePicker.Default.PickAsync(options);
 
if (results is null)
{
return;
}
 
// 安装 APK
InstallApk(results.FullPath, activity);
}
catch (Exception ex)
{
// 处理错误
Console.WriteLine($"更新失败: {ex.Message}");
if (App.Current?.MainPage != null)
{
await App.Current.MainPage.DisplayAlertAsync("错误", $"更新失败: {ex.Message}", "确定");
}
}
}
 
private static void InstallApk(string apkPath, Activity? activity)
{
var file = new Java.IO.File(apkPath);
var uri = AndroidX.Core.Content.FileProvider.GetUriForFile(activity, $"{activity.PackageName}.fileprovider", file);
 
var intent = new Intent(Intent.ActionView);
intent.SetDataAndType(uri, "application/vnd.android.package-archive");
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
intent.AddFlags(ActivityFlags.NewTask);
 
activity.StartActivity(intent);
}
}

以上为整个项目实现安装Apk的代码,想要获取源码的话,可以从
https://github.com/mzy666888/MauiUpdateApp中获取,欢迎给个Star

参考:https://www.cnblogs.com/MASA/p/16612541.html

作者:芝麻麻雀
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
posted @ 2026-03-05 23:20  China Soft  阅读(0)  评论(0)    收藏  举报