Android N:PrintManager.print() 结果 java.lang.IllegalStateException:只能从 activity 打印

Android N: PrintManager.print() results in java.lang.IllegalStateException: Can print only from an activity

我的应用程序使用 PrintManager 进行 PDF 打印。此功能 运行 在 Android L 和 M 中很好,但在 Android N 下失败。

在 onOptionsItemSelected() 的选项菜单中的非片段 activity 中调用打印操作。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
    String jobName = "createPDFReport";
    printManager.print(jobName, new InterimReportAdapter(AuditValidation.this, auditObject), new PrintAttributes.Builder().build());
}

Android N 次抛出

FATAL EXCEPTION: ec.kat.kataudit, PID: 4052
java.lang.IllegalStateException: Can print only from an activity
at android.print.PrintManager.print(PrintManager.java:525)
at ec.kat.kataudit.AuditValidation.onOptionsItemSelected(AuditValidation.java:124)
at android.app.Activity.onMenuItemSelected(Activity.java:3204)
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:408)
at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
...

AuditValidation.java:124 指向 printManager.print() 调用。

Activity 扩展 android.support.v7.app.AppCompatActivity。 编译目标版本为 25,应用程序正在使用最新的库(截至今天为 25.3.1)。

非常感谢任何想法!

此致!

发现问题。在我的 activity 的 attachBaseContext() 中,我实现了语言交换,其中 Android N 通过 createConfigurationContext() 创建了一个新的上下文。这显然会使 PrintManager 实例正在使用的引用无效,从而导致上述 IllegalStateException。 我现在必须为此找到解决方法。

编辑: 我的解决方案是将传递给 attachBaseContext() 的原始上下文的引用存储在我的 activity 的成员中。然后通过在原始上下文引用上调用 getSystemService() 来检索 PrintManager 实例,而不是激活的引用。

private Context primaryBaseActivity;//THIS WILL KEEP ORIGINAL INSTANCE

@Override
protected void attachBaseContext(Context newBase) {
    primaryBaseActivity=newBase;//SAVE ORIGINAL INSTANCE

    /*Some locale handling stuff right here*/
    /*LocaleHelper's onAttach is returning a *new* context in Android N which will void PrintManager's context*/
    super.attachBaseContext(LocaleHelper.onAttach(newBase,appLocale));

}

开始打印时(PDF 生成):

PrintManager printManager = (PrintManager) primaryBaseActivity.getSystemService(Context.PRINT_SERVICE);

在您的 activity

中使用它
private Context primaryBaseActivity;//THIS WILL KEEP ORIGINAL INSTANCE
@Override
protected void attachBaseContext(Context base) {
    primaryBaseActivity=base;
    super.attachBaseContext(base);
}

并替换这一行

PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE); 

 PrintManager  printManager = (PrintManager) primaryBaseActivity.getSystemService(Context.PRINT_SERVICE);