Android N:PrintManager.print()导致java.lang.IllegalStateException:只能从活动打印

问题描述 投票:2回答:3

我的应用程序使用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)。

任何想法都非常感谢!

最好的祝福!

java android pdf-generation illegalstateexception
3个回答
12
投票

发现问题。在我的活动的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);

0
投票

你可以试试这个:

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);
    }
}

-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);
© www.soinside.com 2019 - 2024. All rights reserved.