【问题标题】:Find out if a package was installed successfully查看软件包是否安装成功
【发布时间】: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 个包的当前版本。
  • 提示安装
  • 每隔 xy 秒,再次获取软件包版本并与原始版本进行比较
  • 如果不同,则表示包已成功安装,并为第 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


    【解决方案1】:

    您可以使用BroadcastReceiver 来检测PACKAGE_ADDEDPACKAGE_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.
        }
    }
    

    请注意,新安装的包收不到这个广播。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-23
      • 2019-07-14
      • 2013-10-02
      • 1970-01-01
      相关资源
      最近更新 更多