![](/img/trans.png)
[英]How to install/update/remove APK using “PackageInstaller” class in Android L?
[英]Android PackageInstaller not installing APK
你好 StackOverflow 用戶,
我在 Play 商店之外有一個 Android 應用程序。 它通過下載新的 APK 並使用 Intent 調用安裝程序對話框來更新自身。 更新功能不再適用於 Android 10。
我現在需要在 Android 10 上使用 PackageInstaller API,但我無法讓它工作。 我的應用程序不是設備或配置文件所有者,但由於我不想進行靜默安裝,所以我認為應該沒問題。
我的問題是,一旦我提交會話,絕對不會發生任何事情。
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,您需要確保以下幾點:
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();
}
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
PackageManager.CanRequestPackageInstalls()
來檢查是否是這種情況。 如果此函數返回 false,您可以使用以下代碼打開應用程序選項窗口:StartActivity(new Intent(
Android.Provider.Settings.ActionManageUnknownAppSources,
Android.Net.Uri.Parse("package:" + Android.App.Application.Context.PackageName)));
因此用戶可以輕松設置開關以啟用此功能。
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.