How do I print a WebView using KitKat 4.4 print API via reflection?

余生长醉 提交于 2019-12-01 11:33:40

It's an old one but printing is kind of usefull so this could be good to work correctly. (Without reflection ;))

A better way to work with devices version. No try-catch needed, just need to add some messages before the return or you just hide the button/menu/... depending on the same condition.

@TargetApi(Build.VERSION_CODES.KITKAT)
    private void createWebPrintJob(WebView webView) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) 
            return;

        // Get a PrintManager instance
        PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);

        // Get a print adapter instance
        PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter();

        // Create a print job with name and adapter instance
        String jobName = getString(R.string.app_name) + " Document";
        printManager.print(jobName, printAdapter,
                new PrintAttributes.Builder().build());

    }

The printJob will be execute only with SDK 19 and above

Here is my solution:

public void print(WebView webView) {
    //PrintManager
    String PRINT_SERVICE = (String) Context.class.getDeclaredField("PRINT_SERVICE").get(null);
    Object printManager = mActivity.getSystemService(PRINT_SERVICE);

    //PrintDocumentAdapter
    Class<?> printDocumentAdapterClass = Class.forName("android.print.PrintDocumentAdapter");
    Method createPrintDocumentAdapterMethod = webview.getClass().getMethod("createPrintDocumentAdapter");
    Object printAdapter = createPrintDocumentAdapterMethod.invoke(webview);

    //PrintAttributes
    Class<?> printAttributesBuilderClass = Class.forName("android.print.PrintAttributes$Builder");
    Constructor<?> ctor = printAttributesBuilderClass.getConstructor();
    Object printAttributes = ctor.newInstance(new Object[] {});
    Method buildMethod = printAttributes.getClass().getMethod("build");
    Object printAttributesBuild = buildMethod.invoke(printAttributes);

    //PrintJob
    String jobName = "My Document";
    Method printMethod = printManager.getClass().getMethod("print", String.class, printDocumentAdapterClass, printAttributesBuild.getClass());
    Object printJob = printMethod.invoke(printManager, jobName, printAdapter, printAttributesBuild);

    // Save the job object for later status checking
    mPrintJobs.add(printJob);
}

Just make sure this is called on the main thread. Also note: You need to use a try catch. Devices which are not running 4.4+ will crash if you don't.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!