无法解析具有 "downloads" 权限的内容提供者时 PackageInstaller 崩溃
PackageInstaller crash when unable to resolve content provider with "downloads" authority
关于一些背景知识,我正在用 Xamarin 为企业编写一个 Android 应用程序,它应该能够自行更新,而不是通过 Play 商店。特别是有一台设备无法自行更新,我不明白为什么。
更新代码如下所示:
try
{
var intent = new Intent(Intent.ActionInstallPackage);
intent.SetFlags(ActivityFlags.NewTask);
var file = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.Path + "/com.mycompany.appname.apk");
var uri = FileProvider.GetUriForFile(this, "com.mycompany.appname.update_file_provider", file);
GrantUriPermission("com.google.android.packageinstaller", uri, ActivityFlags.GrantReadUriPermission);
intent.SetDataAndType(uri, "application/vnd.android.package-archive");
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
var notification = GetNotificationBuilder(installedVersion, latestVersion, this)
.SetContentText("Download complete.")
.AddAction(new NotificationCompat.Action(Resource.Drawable.ic_note_add_black_24dp, "Install", pendingIntent))
.SetAutoCancel(true)
.Build();
NotificationManagerCompat.From(this).Notify(NotificationId, notification);
StopSelf();
}
catch (Exception e)
{
var notification = GetNotificationBuilder(installedVersion, latestVersion, this)
.SetContentText("Failed to install update: " + e.Message)
.SetAutoCancel(true)
.Build();
NotificationManagerCompat.From(this).Notify(NotificationId, notification);
StopSelf();
return;
}
当它运行时,我收到一条消息说,"PackageInstaller has stopped." 堆栈跟踪显示这是由于软件包安装程序应用程序中的 NPE 造成的:
12-02 17:37:17.153 4897 4897 E AndroidRuntime: FATAL EXCEPTION: main
12-02 17:37:17.153 4897 4897 E AndroidRuntime: Process: com.google.android.packageinstaller, PID: 4897
12-02 17:37:17.153 4897 4897 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.android.packageinstaller/com.android.packageinstaller.InstallStart}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.pm.ComponentInfo.getComponentName()' on a null object reference
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2785)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2863)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.-wrap11(Unknown Source:0)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1596)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6537)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:465)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.pm.ComponentInfo.getComponentName()' on a null object reference
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.packageinstaller.InstallStart.isSystemDownloadsProvider(InstallStart.java:230)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.packageinstaller.InstallStart.getOriginatingUid(InstallStart.java:222)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.packageinstaller.InstallStart.onCreate(InstallStart.java:73)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7023)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7014)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2738)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: ... 9 more
郑重声明:此特定设备是 运行 Android 8.1。我已经在其他设备 运行 Android 8.0、Android 10 和 Android 7 上测试过,没有任何问题,但我没有任何其他设备具有完全相同的功能Android 用于测试的版本。
编辑 我意识到我应该对标题做更多的解释。我实际上已经查看了 source code for the PackageInstaller app,在该堆栈跟踪出现的位置附近,看来这一行是此 NPE 的原因:
final String downloadProviderPackage = getPackageManager().resolveContentProvider(
DOWNLOADS_AUTHORITY, 0).getComponentName().getPackageName();
DOWNLOADS_AUTHORITY
是一个值为 "downloads"
的常量字符串,对 resolveContentProvider()
的调用返回空值。不清楚的是为什么这个特定设备会出现这种情况,而其他设备不会出现这种情况,或者如何修复它。
问题原来是下载管理器被禁用了。它似乎仅在 android 8.0 和 8.1 中是一个问题。我仍然不确定它是如何开始被禁用的,但我的解决方案是使用 blackapps 推荐的 null 检查,并包含一个提示,让用户在检测到这种情况时重新启用它。
关于一些背景知识,我正在用 Xamarin 为企业编写一个 Android 应用程序,它应该能够自行更新,而不是通过 Play 商店。特别是有一台设备无法自行更新,我不明白为什么。
更新代码如下所示:
try
{
var intent = new Intent(Intent.ActionInstallPackage);
intent.SetFlags(ActivityFlags.NewTask);
var file = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.Path + "/com.mycompany.appname.apk");
var uri = FileProvider.GetUriForFile(this, "com.mycompany.appname.update_file_provider", file);
GrantUriPermission("com.google.android.packageinstaller", uri, ActivityFlags.GrantReadUriPermission);
intent.SetDataAndType(uri, "application/vnd.android.package-archive");
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
var notification = GetNotificationBuilder(installedVersion, latestVersion, this)
.SetContentText("Download complete.")
.AddAction(new NotificationCompat.Action(Resource.Drawable.ic_note_add_black_24dp, "Install", pendingIntent))
.SetAutoCancel(true)
.Build();
NotificationManagerCompat.From(this).Notify(NotificationId, notification);
StopSelf();
}
catch (Exception e)
{
var notification = GetNotificationBuilder(installedVersion, latestVersion, this)
.SetContentText("Failed to install update: " + e.Message)
.SetAutoCancel(true)
.Build();
NotificationManagerCompat.From(this).Notify(NotificationId, notification);
StopSelf();
return;
}
当它运行时,我收到一条消息说,"PackageInstaller has stopped." 堆栈跟踪显示这是由于软件包安装程序应用程序中的 NPE 造成的:
12-02 17:37:17.153 4897 4897 E AndroidRuntime: FATAL EXCEPTION: main
12-02 17:37:17.153 4897 4897 E AndroidRuntime: Process: com.google.android.packageinstaller, PID: 4897
12-02 17:37:17.153 4897 4897 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.android.packageinstaller/com.android.packageinstaller.InstallStart}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.pm.ComponentInfo.getComponentName()' on a null object reference
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2785)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2863)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.-wrap11(Unknown Source:0)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1596)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6537)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:465)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.pm.ComponentInfo.getComponentName()' on a null object reference
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.packageinstaller.InstallStart.isSystemDownloadsProvider(InstallStart.java:230)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.packageinstaller.InstallStart.getOriginatingUid(InstallStart.java:222)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at com.android.packageinstaller.InstallStart.onCreate(InstallStart.java:73)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7023)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7014)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2738)
12-02 17:37:17.153 4897 4897 E AndroidRuntime: ... 9 more
郑重声明:此特定设备是 运行 Android 8.1。我已经在其他设备 运行 Android 8.0、Android 10 和 Android 7 上测试过,没有任何问题,但我没有任何其他设备具有完全相同的功能Android 用于测试的版本。
编辑 我意识到我应该对标题做更多的解释。我实际上已经查看了 source code for the PackageInstaller app,在该堆栈跟踪出现的位置附近,看来这一行是此 NPE 的原因:
final String downloadProviderPackage = getPackageManager().resolveContentProvider(
DOWNLOADS_AUTHORITY, 0).getComponentName().getPackageName();
DOWNLOADS_AUTHORITY
是一个值为 "downloads"
的常量字符串,对 resolveContentProvider()
的调用返回空值。不清楚的是为什么这个特定设备会出现这种情况,而其他设备不会出现这种情况,或者如何修复它。
问题原来是下载管理器被禁用了。它似乎仅在 android 8.0 和 8.1 中是一个问题。我仍然不确定它是如何开始被禁用的,但我的解决方案是使用 blackapps 推荐的 null 检查,并包含一个提示,让用户在检测到这种情况时重新启用它。