首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓PackageInstaller没有安装APK

安卓PackageInstaller没有安装APK
EN

Stack Overflow用户
提问于 2020-01-10 16:48:31
回答 1查看 10.6K关注 0票数 6

你好,StackOverflow用户,

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

我现在需要在Android10上使用PackageInstaller API,但我无法让它工作。我的应用程序不是一个设备或配置文件所有者,但由于我不想一个无声的安装,所以我认为它应该是好的。

我的问题是,一旦我提交会议,绝对不会发生任何事情。

代码语言:javascript
复制
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,而不会出现故障。在谷歌上搜索错误并没有给我带来任何线索。

我怎样才能解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-19 10:58:44

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

  • 不使用语句,也不尝试在AddApkToInstallSession方法中释放任何内容。释放会导致安装失败。使用“尝试/最后并关闭”:

代码语言:javascript
复制
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“方法,因为您需要确认APK文件

的安装。

代码语言:javascript
复制
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;
        }
    }
}

覆盖“LaunchMode.SingleTop

  • The”方法的
  • 活动必须将LaunchMode设置为LaunchMode用户,必须为尝试安装APK文件的应用程序提供安装PackageManager.CanRequestPackageInstalls()的必要权限。您可以通过调用PackageManager.CanRequestPackageInstalls()来检查是否是这样的。如果此函数返回false,则可以使用以下代码打开应用程序选项窗口:

代码语言:javascript
复制
StartActivity(new Intent(
            Android.Provider.Settings.ActionManageUnknownAppSources,
            Android.Net.Uri.Parse("package:" + Android.App.Application.Context.PackageName)));

因此,用户可以轻松地设置开关以启用该开关。

这是我初始化APK installation:的主要方法

代码语言:javascript
复制
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);
}

  • 如果您正在小米设备上调试,您必须在developer选项下禁用MIUI优化。否则,安装将失败,权限被拒绝。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59685804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档