查看包是否安装成功
Find out if a package was installed successfully
我正在尝试向 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 本机 returns 结果,我不清楚。
- 使用 BroadcastReceiver。这假定 Android 在成功安装任何应用程序时本机发送广播消息。
我的想法能行得通吗?或者其他什么?
您可以使用 BroadcastReceiver
检测 PACKAGE_ADDED、PACKAGE_REMOVED
消息::
在您的清单中:
<receiver android:name=".AppStatusReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
</intent-filter>
</receiver>
然后创建广播接收器:
[BroadcastReceiver(Enabled = true, Exported = false)]
public class SampleReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Do stuff here.
}
}
请注意,新安装的软件包不会收到此广播。
我正在尝试向 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 本机 returns 结果,我不清楚。
- 使用 BroadcastReceiver。这假定 Android 在成功安装任何应用程序时本机发送广播消息。
我的想法能行得通吗?或者其他什么?
您可以使用 BroadcastReceiver
检测 PACKAGE_ADDED、PACKAGE_REMOVED
消息::
在您的清单中:
<receiver android:name=".AppStatusReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
</intent-filter>
</receiver>
然后创建广播接收器:
[BroadcastReceiver(Enabled = true, Exported = false)]
public class SampleReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Do stuff here.
}
}
请注意,新安装的软件包不会收到此广播。