Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For an Android app, the official Kotlin approach is to load the page in a WebView, wait for its load callback, create a PrintDocumentAdapter, and submit it to Android’s PrintManager. The result is an Android print job; the user or an installed print service can choose an option such as Save as PDF. This is different from silently writing a PDF to a file path.

The workflow below covers remote URLs, local HTML, JavaScript-dependent pages, lifecycle safety, dynamic content, print limitations, troubleshooting, and alternatives when you need direct file output.

What the Android WebView method actually does

Android’s documented HTML-printing flow connects three APIs:

  1. WebView.loadUrl() (or loadDataWithBaseURL() for HTML you already have) renders the page.
  2. WebView.createPrintDocumentAdapter() creates an adapter for that rendered content.
  3. PrintManager.print() starts Android’s system print UI.

Android does not present this combination as a one-call “URL to PDF file” API. The print service controls the final save operation. That makes it a good fit when your app should use the device’s normal print workflow, but not when you must silently create a PDF at a known path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Yojaro 4Pack Silicone Suction Phone Case Mount, Silicon Adhesive Smartphones Stand Sticky, Hands-Free Phone Accessories Holder for Selfies and Videos (Black & White & Translucent & Light Pink)
  • 【Strong Adsorption】The inspiration of the silicone phone suction case comes from the adhesive force of the octopus. Each suction cup phone mount is 3.15 inches long and 2.17 inches wide, with 24 independent suction cups providing a stronger and more stable suction force, so you don't have to worry about your phone falling during use.
  • 【Back of Phone Suction Grip】Remove the adhesive film on the phone suction cup and stick it on the phone case. You can then fix the phone on any smooth surface, which is very convenient. (The phone suction cup cannot be removed and reused after being attached to the phone case. It is recommended to attach it to a regular phone case, not a valuable one.)
  • 【Widely Used】Our non-slip silicone phone sticky grip mount attaches to almost any flat phone case and make it compatible with common mobile phones such as iPhone and Android.You can shoot, watch videos or video calls in the kitchen, gym, dance studio, bathroom and other places.
  • 【Capture the Wonderful Picture】Whether you are a TikTok creator or just like to share videos and photos, this phone suction cup can help you hands-free capture wonderful videos and photos for sharing with friends.
  • 【Note】You can fix the phone suction cup on a smooth surface such as a mirror or glass. If necessary, wipe the suction cup with a damp cloth to obtain stronger suction. Before releasing your hand, make sure the phone is firmly fixed. (Not applicable to rough walls, wooden surfaces, and other uneven surfaces)

Prerequisites and project setup

Manifest permission

A remote page requires internet access. Add this outside the <application> element in AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

JavaScript is disabled in a WebView by default. Enable it only when the target page needs it, and treat remote content as untrusted input.

Keep work on the WebView’s creating thread

WebView methods must run on the thread that created the view, normally the Android main thread. Create and configure the WebView there, and avoid touching it from a background callback.

Complete Kotlin example: URL to Android print flow

The following Activity-level example retains the WebView until the print adapter has been handed to PrintManager. Adapt the ownership to your Activity or Fragment lifecycle.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Apple EarPods Headphones with USB-C Plug, Wired Ear Buds with Built-in Remote to Control Music, Phone Calls, and Volume
  • SUPERIOR COMFORT — Unlike traditional circular ear buds, the design of EarPods is defined by the geometry of the ear. Which makes them more comfortable for more people than any other ear bud–style headphones.
  • HIGH-QUALITY AUDIO — The speakers inside EarPods have been engineered to maximize sound output and minimize sound loss, which means you get high-quality audio.
  • BUILT-IN REMOTE — EarPods with USB-C plug also include a built-in remote that lets you adjust the volume, control the playback of music and video, and answer or end calls with a pinch of the cord.
  • COMPATIBILITY — Works with all devices that have a USB-C port.
  • INTEGRATED MICROPHONE — A built-in microphone precisely captures your voice while you’re on the phone, taking a FaceTime call, or summoning Siri — so you’re always heard loud and clear.
import android.app.Activity
import android.content.Context
import android.print.PrintAttributes
import android.print.PrintManager
import android.webkit.WebView
import android.webkit.WebViewClient

class MainActivity : Activity() {
    private var printWebView: WebView? = null

    fun printUrl(url: String) {
        val webView = WebView(this)
        printWebView = webView

        webView.settings.javaScriptEnabled = true
        webView.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView, loadedUrl: String) {
                val printManager =
                    getSystemService(Context.PRINT_SERVICE) as PrintManager
                val adapter = view.createPrintDocumentAdapter("Web page")
                printManager.print(
                    "Web page",
                    adapter,
                    PrintAttributes.Builder().build()
                )

                // The adapter has received the WebView. Release your field
                // when your app no longer needs to retain it.
                printWebView = null
            }
        }

        webView.loadUrl(url)
    }
}

Call printUrl("https://example.com") from the main thread. The print dialog appears after WebView reports that the page finished loading.

Why the field matters

Android’s guide retains a reference to the WebView until the adapter is created and passed to PrintManager. Releasing it too early can allow the view to be collected or destroyed during conversion. In production, also clean up a WebView when the Activity or Fragment is destroyed, and prevent duplicate submissions.

Waiting for content that loads after onPageFinished

onPageFinished() means WebView reported the document load complete. It does not prove that a single-page application has finished rendering, that lazy images have appeared, or that an asynchronous API request has returned.

Use a page-specific readiness signal

For pages you control, expose a DOM marker after the required data and images are ready, then poll it with evaluateJavascript() before printing. A simplified pattern is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
PopSockets Adhesive Phone Grip, Holder- Black
  • Secure Hold: Our PopSockets adhesive phone grip gives your cell phone a secure, comfortable hold in hand to help prevent drops while texting, taking photos, or scrolling on the go. Designed to stick firmly to most phone cases and devices.
  • Hands-Free Made Easy: Easily turn your PopSocket into a phone stand to prop up your phone anywhere — perfect for watching videos, video calls, or following recipes. A must-have phone holder that keeps your device secure and ready for anything.
  • Compatibility: Works with all phones, tablets, and Kindles. Sticks best to smooth, hard plastic cases and may not adhere to silicone or textured cases. Easily swap your PopTop to change up your style — just close the grip, press down, twist 90°, and snap on a new top.
  • Black PopSockets: Simple, refined, and endlessly versatile — a timeless essential for any phone.
  • PopSockets Ecosystem: Mix and match your favorite PopSockets products — from grips and wallets to cases and mounts — all designed to work together seamlessly.
private fun waitForReady(webView: WebView, onReady: () -> Unit) {
    webView.evaluateJavascript(
        "document.documentElement.dataset.pdfReady === 'true'"
    ) { result ->
        if (result == "true") onReady()
        else webView.postDelayed({ waitForReady(webView, onReady) }, 250)
    }
}

Use a timeout and a maximum number of attempts in a real implementation. For third-party pages, you may not have a reliable readiness marker; test representative URLs and decide whether a fixed delay, a network-idle heuristic, or a different conversion service is acceptable.

Navigation and load errors

Override WebView error callbacks to show a useful message instead of opening an empty print job. Handle redirects and confirm that the final URL is allowed by your app’s security policy. Do not treat a successful HTTP response as proof that the visual page is complete.

Printing local HTML and relative assets

When the source is an HTML string, use loadDataWithBaseURL() so relative images, stylesheets, and links resolve against the intended origin:

val html = """
    <html><body>
      <h1>Invoice</h1>
      <img src="images/logo.png" alt="Logo">
    </body></html>
""".trimIndent()

webView.loadDataWithBaseURL(
    "https://your.example/",
    html,
    "text/html",
    "UTF-8",
    null
)

The base URL is what lets WebView resolve images/logo.png. If all assets are inline, a null or data base can be sufficient, but verify fonts and images on the Android versions you support.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
360° Rotating Stainless Steel Phone Tether Tab (Silvery 3-Pack) - Universal for iPhone & Other Phones (Fits Wristbands/Necklaces/Crossbody Straps)
  • [360 ° Flexible Rotation Design] Comes with a rotatable lanyard ring that supports 360 ° free rotation, effectively solving the problem of twisted and tangled lanyards
  • [Wide compatibility] The ultra-thin 0.02-inch design does not block the charging port at all, and both wired and wireless charging can be used directly without removing the pad. Compatible with most smartphones such as iPhone, compatible with various wristbands, lanyards, crossbody straps, and keychains
  • [Durable and Portable Material] Premium rust-resistant stainless steel material with good flexibility, which not only avoids scratching the phone case, but also has excellent anti rust and anti fading performance
  • [Multi scenario Practical] Paired with a lanyard or wristband, hands-free use can be achieved. The phone is within reach and not easily dropped, ideal for daily commuting and outdoor activities. Suitable for full coverage phone cases, does not support half coverage phone cases
  • [Quality Service] If you find any damage or other issues with the product upon receipt, please contact us immediately. We will handle it quickly

What Android’s built-in print path cannot do

  • No application-added headers or footers: Android documents that headers, footers, and page numbers cannot be added to the document through this HTML-printing API.
  • No page-range control in your adapter: the documented WebView route does not provide your app with page-range selection.
  • Limited CSS print support: CSS print attributes such as landscape properties are not supported by this path.
  • One print job per WebView: do not submit overlapping jobs from the same WebView.
  • No JavaScript-triggered printing: a page calling browser-style JavaScript printing does not replace your app’s explicit adapter submission.
  • System UI is involved: availability of Save as PDF depends on an installed print service and device configuration.

These constraints are reasons to evaluate a dedicated HTML-to-PDF SDK when direct output, page templates, or stronger layout control is a requirement. They are not evidence that any SDK will render every modern site identically; validate the pages that matter to your product.

Choosing an alternative conversion approach

Approach Documented input/output Best fit Trade-offs to verify
Android WebView plus PrintManager URL or HTML rendered in WebView; system print job An app that should use Android print services Print limitations, user-driven save, dynamic-page timing
Apryse Android HTML-to-PDF SDK URL, HTML string, or WebView input; callback includes an output path; Android API 19 or later is stated in its documentation Direct SDK conversion with a callback and file output Vendor dependency, licensing, exact JavaScript/resource behavior, and target-page fidelity
iText HTML conversion from a URL stream Documentation shows opening a URL stream and passing it to HTML-to-PDF conversion JVM or stream-oriented pipelines where you supply HTML and resources The cited material does not establish it as a drop-in Android WebView renderer or confirm current mobile compatibility

Before selecting an SDK, compare system print UI versus direct file ownership, JavaScript and external-resource handling, orientation and header controls, minimum Android API, licensing, and operational cost. No universal speed or fidelity ranking is established for arbitrary websites.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo can return a URL capture as PNG, JPEG, WebP, or PDF through one request, which is useful when conversion belongs on a server rather than inside an Android process. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers.

For a PDF response, call the API endpoint and save the response body:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" 
  -d access_key=YOUR_API_KEY 
  --data-urlencode url=https://stripe.com 
  -o page.pdf

See the ScreenshotNeo documentation for PDF parameters and the other capture controls. The service also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Start at the free ScreenshotNeo sign-up.

Best Value
Anteel 2 Pack Silicone Suction Cup Phone Case Mount Double Sided, Hands-Free Silicon Phone Grip with Higher Suction Power for Selfies and Videos, Non Slip Phone Accessories (LightPink&White)
  • 【PKYAA Double Sided Silicone Suction Phone Case Mount】PKYAA With Double Sided 40 Strong and Reliable individual suction cups, PKYAA provides a thicken and upgraded universal silicon suction mount for your phone.
  • 【Friendly to Content Creators】If you are a content creator or an online influencer, you can create videos anywhere with this suction mount completely hands free with this silicone cell phone mount for cases.
  • 【HANDS-FREE & Adhere to Mirrors】This Double Sided silicone suction phone case mount allows you to stick your phone to the mirror easily. No longer holding your phone in one hand to watch video tutorials while making up.
  • 【Strong Grip on the Smooth Surface】You can easily hang your phone anywhere with a smooth surface. All you do is you clean off your phone and smooth surface. It is STURDY and it not only sticks to mirrors, it also sticks to windows, it sticks to refrigerators, tiles and other clean, flat surfaces.
  • 【Press Down Firmly Every 30 Minutes】Use your palm or fingers to press the phone down firmly and check it's secure before letting go. Apply even pressure for a few seconds to allow the suction cup to adhere properly. To maintain the grip and prevent accidental falls, it's a good practice to periodically reapply pressure to the suction cup.

Equivalent requests from Python and Node.js

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("page.pdf", "wb").write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('page.pdf', Buffer.from(await res.arrayBuffer()));

Troubleshooting checklist

The page is blank or the print dialog opens too early

  • Confirm INTERNET permission and the final redirected URL.
  • Enable JavaScript if the page depends on it.
  • Wait for a page-specific readiness marker rather than relying only on onPageFinished().
  • Check that images and stylesheets are reachable and that the base URL is correct for local HTML.

Images or fonts are missing

Inspect relative URLs, HTTPS access, authentication requirements, and mixed-content restrictions. Inline critical assets or host them at a reachable HTTPS origin. A successful document load does not guarantee every subresource loaded.

The app crashes when printing

Ensure all WebView calls occur on the creating thread, retain the WebView until adapter handoff, and prevent a second print job from starting on the same WebView. Avoid destroying the Activity or its WebView while conversion is in progress.

The PDF needs page numbers, landscape layout, or a chosen page range

Those controls are not provided by the documented WebView print path. Add print styling inside the HTML where supported, or evaluate a dedicated SDK whose documented output controls match your requirements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The output differs between devices

WebView rendering, installed print services, Android releases, fonts, network responses, and device settings can differ. Test the Android API levels and representative pages you support; there is no cited universal quality or speed guarantee.

Production checklist

  • Validate and restrict URLs before loading them.
  • Show progress and a clear error for navigation or resource failures.
  • Use a timeout for dynamic readiness checks.
  • Release WebViews with the Activity or Fragment lifecycle.
  • Prevent duplicate print submissions.
  • Test authenticated pages, redirects, lazy images, long documents, and offline failure.
  • Decide explicitly whether the product needs Android’s print UI or a PDF file produced directly by code.

Frequently Asked Questions

Can Kotlin convert a URL directly to a PDF without showing Android’s print UI?

Not with the documented WebView plus PrintManager workflow; that route starts a print job. Use a conversion SDK or a server-side service when your app must receive a file directly.

Does onPageFinished mean a JavaScript application is ready to print?

No. It reports WebView’s document-load completion, while application data, lazy images, and asynchronous rendering may still be in progress.

Can I use the same WebView for normal browsing and printing?

You can, but a dedicated off-screen WebView is safer for printing because drawing the same WebView during conversion is undefined. Keep the printing view isolated when possible.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.