我的应用程序使用PrintManager进行PDF打印。此功能在Android L和M中运行良好,但在Android N下失败。
在onOptionsItemSelected()的选项菜单中的非片段活动中调用打印操作。
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,app正在使用最新的库(截至今天为25.3.1)。
任何想法都非常感谢!
最好的祝福!
发现问题。在我的活动的attachBaseContext()中,我实现了一个语言交换,它让Android N通过createConfigurationContext()创建一个新的上下文。这显然使PrintManager实例使用的引用无效,导致上面的IllegalStateException。我现在必须为此找到解决方法。
编辑:我的解决方案是存储传递给我的活动成员中的attachBaseContext()的原始上下文的引用。然后通过在原始Context引用上调用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);
你可以试试这个:
public void printDocument(WebView webView, String title)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
//noinspection deprecation
PrintDocumentAdapter printDocumentAdapter = webView.createPrintDocumentAdapter();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) printDocumentAdapter = webView.createPrintDocumentAdapter(title);
String documentName = mContext.getString(R.string.project_name)+" - "+title;
PrintJob printJob = printManager.print(documentName, printDocumentAdapter, new PrintAttributes.Builder().build());
List<PrintJob> printJobs = printManager.getPrintJobs();
printJobs.add(printJob);
}
else
{
showToast(mContext.getString(R.string.mytools_printing_not_supported), 1);
}
}
在你的活动中使用它
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);