【发布时间】:2021-03-08 07:47:43
【问题描述】:
我正在尝试向 Xamarin Android 应用添加自动更新功能。
当它启动时,应用程序会检查当前版本是否被允许,如果不允许,则从数据库中检索所有要更新的包(一个或多个)。
然后它会下载所有包并将它们保存到磁盘。下载完所有包后,我会提示 android 按顺序安装它们:
foreach (UpdatedApp app in apps)
{
InstallPackage(app);
}
private void InstallPackage(UpdatedApp app)
{
Java.IO.File file = new Java.IO.File(app.Path);
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
{
Intent intent = new Intent(Intent.ActionInstallPackage);
intent.SetData(FileProvider.GetUriForFile(this, $"{PackageName}.fileprovider", file));
intent.SetFlags(ActivityFlags.GrantReadUriPermission);
StartActivity(intent);
}
else
{
Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(Android.Net.Uri.FromFile(file), "application/vnd.android.package-archive");
intent.AddFlags(ActivityFlags.NewTask);
StartActivity(intent);
}
只有一个包要安装的时候效果很好,但是当至少有两个的时候,我基本上提示android同时安装包,只会安装第一个包。
我添加了一点逻辑来规避这个问题:
- 获取第 N 个包的当前版本。
- 提示安装
- 每隔 x 秒 y 秒,再次获取软件包版本并与原始版本进行比较
- 如果不同,则表示包已成功安装,并为第 N+1 个包重复该过程
- 否则取消任何进一步的安装
这是更新后的代码:
foreach (UpdatedApp app in apps)
{
string versionName = GetPackageVersion(app);
InstallPackage(app);
bool installed = await HasPackageBeenInstalled(app, versionName);
if (!installed)
break;
}
private async Task<bool> HasPackageBeenInstalled(UpdatedApp app, string oldVersion)
{
int count = 0;
do
{
await Task.Delay(1000);
string newVersion = GetPackageVersion(app);
if (newVersion != oldVersion)
return true;
count++;
}
while (count < 20);
return false;
}
private string GetPackageVersion(UpdatedApp app)
{
try
{
PackageInfo packageInfo = PackageManager.GetPackageInfo(app.PackageName, 0);
return packageInfo.VersionName;
}
catch (PackageManager.NameNotFoundException e)
{
return null;
}
}
它确保我只在安装前一个包后提示安装一个包。
我想知道是否有更好的方法来做到这一点?我想到了两件事:
- 使用 StartActivityForResult 而不是 StartActivity。这假设 Android 本身返回一个结果,我不清楚。
- 使用BroadcastReceiver。这假设当任何应用成功安装时,Android 会本机发送一条广播消息。
我的任何想法都行得通吗?还是别的什么?
【问题讨论】:
标签: c# android xamarin installation package