gpt4 book ai didi

Android PackageInstaller 未安装 APK

转载 作者:行者123 更新时间:2023-12-03 23:49:34 24 4
gpt4 key购买 nike

您好 StackOverflow 用户,

我在 Play 商店之外有一个 Android 应用程序。它通过下载新的 APK 并使用 Intent 调用安装程序对话框来更新自身。更新功能不再适用于 Android 10。

我现在需要在 Android 10 上使用 PackageInstaller API,但我无法让它工作。我的应用程序不是设备或个人资料所有者,但由于我不想要静默安装,所以我认为应该没问题。

我的问题是,一旦我提交 session ,绝对没有任何 react 。

PackageInstaller installer = activity.PackageManager.PackageInstaller;
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstallMode.FullInstall);
int sessionId = installer.CreateSession(sessionParams);
PackageInstaller.Session session = installer.OpenSession(sessionId);

var input = new FileStream(pfad, FileMode.Open, FileAccess.Read);
var packageInSession = session.OpenWrite("package", 0, -1);
input.CopyTo(packageInSession);
packageInSession.Close();
input.Close();

//That this is necessary could be a Xamarin bug.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

Intent intent = new Intent(activity, activity.Class);
intent.SetAction("com.example.android.apis.content.SESSION_API_PACKAGE_INSTALLED");
PendingIntent pendingIntent = PendingIntent.GetActivity(activity, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.IntentSender;

// Commit the session (this will start the installation workflow).
session.Commit(statusReceiver);

我查看了 DDMS 并没有从中得到任何相关信息。可能感兴趣的一件事是,当我 Dispose()溪流,我得到一个 IOException: write failed (EBADF) bad file descriptor这将表明一个坏的 APK。但我怀疑是不是因为我可以使用文件管理器安装 APK 而不会出现故障。谷歌搜索错误并没有把我带到任何地方。

我该如何解决这个问题?

最佳答案

为了在 Android Q 中成功安装 apk,您需要确保以下几点:

  • 不要使用 using 语句或尝试在 AddApkToInstallSession 方法中处理任何内容。 Dispose 导致安装失败。使用 try/finally 并关闭:

  • private static void AddApkToInstallSession(Context context, Android.Net.Uri apkUri, PackageInstaller.Session session)
    {
    var packageInSession = session.OpenWrite("package", 0, -1);
    var input = context.ContentResolver.OpenInputStream(apkUri);

    try
    {
    if (input != null)
    {
    input.CopyTo(packageInSession);
    }
    else
    {
    throw new Exception("Inputstream is null");
    }
    }
    finally
    {
    packageInSession.Close();
    input.Close();
    }

    //That this is necessary could be a Xamarin bug.
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    }
  • 您必须重写“OnNewIntent”方法,因为您需要一个 Intent 来确认 APK 文件的安装:

  • protected override void OnNewIntent(Intent intent)
    {
    Bundle extras = intent.Extras;
    if (PACKAGE_INSTALLED_ACTION.Equals(intent.Action))
    {
    var status = extras.GetInt(PackageInstaller.ExtraStatus);
    var message = extras.GetString(PackageInstaller.ExtraStatusMessage);
    switch (status)
    {
    case (int)PackageInstallStatus.PendingUserAction:
    // Ask user to confirm the installation
    var confirmIntent = (Intent)extras.Get(Intent.ExtraIntent);
    StartActivity(confirmIntent);
    break;
    case (int)PackageInstallStatus.Success:
    //TODO: Handle success
    break;
    case (int)PackageInstallStatus.Failure:
    case (int)PackageInstallStatus.FailureAborted:
    case (int)PackageInstallStatus.FailureBlocked:
    case (int)PackageInstallStatus.FailureConflict:
    case (int)PackageInstallStatus.FailureIncompatible:
    case (int)PackageInstallStatus.FailureInvalid:
    case (int)PackageInstallStatus.FailureStorage:
    //TODO: Handle failures
    break;
    }
    }
    }
  • 覆盖“OnNewIntent”方法的 Activity 必须将 LaunchMode 设置为 LaunchMode.SingleTop
  • 用户必须已向您尝试安装 APK 文件的应用程序授予安装 APK 所需的权限。您可以通过调用 PackageManager.CanRequestPackageInstalls() 来检查是否是这种情况。 .如果此函数返回 false,您可以使用以下代码打开应用程序选项窗口:
  • StartActivity(new Intent(
    Android.Provider.Settings.ActionManageUnknownAppSources,
    Android.Net.Uri.Parse("package:" + Android.App.Application.Context.PackageName)));

    因此用户可以轻松设置开关以启用此功能。
  • 这是我初始化APK安装的主要方法:

  • public void InstallPackageAndroidQAndAbove(Android.Net.Uri apkUri)
    {
    var packageInstaller = PackageManager.PackageInstaller;
    var sessionParams = new PackageInstaller.SessionParams(PackageInstallMode.FullInstall);
    int sessionId = packageInstaller.CreateSession(sessionParams);
    var session = packageInstaller.OpenSession(sessionId);

    AddApkToInstallSession(apkUri, session);

    // Create an install status receiver.
    var intent = new Intent(this, this.Class);
    intent.SetAction(PACKAGE_INSTALLED_ACTION);
    var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
    var statusReceiver = pendingIntent.IntentSender;

    // Commit the session (this will start the installation workflow).
    session.Commit(statusReceiver);
    }
  • 如果你在小米设备上调试,你必须在开发者选项下禁用 MIUI 优化。否则安装将失败并出现权限被拒绝错误。
  • 关于Android PackageInstaller 未安装 APK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59685804/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com