Creating a Native Android Plugin for HTML to PDF Conversion in Unity
- Gabriel Alabi

- 2 hours ago
- 4 min read
Converting HTML content to PDF within a Unity project on Android can be a challenge. Unity does not provide built-in support for this task, and relying on third-party services or web APIs may introduce latency, privacy concerns, or require internet access. Building a native Android plugin that handles HTML to PDF conversion directly on the device offers a clean, efficient solution. This article walks through how to create such a plugin using Java for Android and C# for Unity integration.
Understanding the Need for a Native Plugin
Unity excels at cross-platform game and app development, but some platform-specific features require native code. PDF generation from HTML is one of those features. While Unity supports Android plugins, the process involves writing Java code that interacts with Android’s native APIs and then calling that code from C# scripts in Unity.
Using a native plugin means:
Faster PDF generation without network dependency
Full control over rendering and PDF settings
Seamless integration with Unity’s workflow
Setting Up the Android Plugin Project
Start by creating an Android Studio project for the plugin. This project will produce a `.aar` file that Unity can import.
Create a new Android Empty Views Activity Project in Android Studio, and set the minimum SDK version to match your Unity Android build target.
Create a new Android Library Module, and set the minimum SDK version to match your Unity Android build target
Create an android.print package under your Android Library Module's java (or kotlin+java) package. This is required because Android's PrintDocumentAdapter and related classes (like PdfDocument) rely on package-private members that are only accessible from within the android.print namespace itself.
Create a file named file_paths.xml inside your Android Library Module's res/xml/ directory. This file is required to configure secure file sharing for viewing the PDF.
Edit the file_paths.xml and edit the AndroidManifest.xml inside your Android Library Module
<!-- file_paths.xml -->
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Internal app files (getFilesDir) -->
<files-path name="internal_files" path="." />
</paths>
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<!-- FileProvider to share files with other apps or access public storage -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>Key Java Classes and Methods
WebView: Renders HTML content.
PrintDocumentAdapter: Used to create PDF from WebView content.
The plugin will expose a method that takes an HTML string and a file path, then generates a PDF saved to that path.
Writing the Java Code for HTML to PDF Conversion
Here is a simplified example of the core Java classes and methods:
public class LearnHtmlToPdfPlugin {
public static void convertHtmlStringToPdf(Context context, String htmlString, String pdfPath, PdfCallback callback) {
((Activity) context).runOnUiThread(() -> {
WebView webView = new WebView(context);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
PrintDocumentAdapter adapter = webView.createPrintDocumentAdapter("doc");
PrintAttributes attrs = new PrintAttributes.Builder()
.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.build();
new PdfPrint(attrs).print(adapter, new File(pdfPath), "doc",
new PdfPrint.CallbackPrint() {
public void onSuccess(String path) { callback.onSuccess(path); }
public void onFailure(String msg) { callback.onFailure(msg); }
});
}
});
webView.loadDataWithBaseURL(null, htmlString, "text/html", "UTF-8", null);
});
}
public interface PdfCallback {
void onSuccess(String filePath);
void onFailure(String errorMessage);
}
}public class PdfPrint {
private final PrintAttributes printAttributes;
public PdfPrint(PrintAttributes printAttributes) {
this.printAttributes = printAttributes;
}
public void print(PrintDocumentAdapter printAdapter, File directory, String fileName, CallbackPrint callback) {
printAdapter.onLayout(null, printAttributes, null,
new PrintDocumentAdapter.LayoutResultCallback() {
@Override
public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES},
getOutputFile(directory, fileName),
new CancellationSignal(),
new PrintDocumentAdapter.WriteResultCallback() {
@Override
public void onWriteFinished(PageRange[] pages) {
callback.onSuccess(new File(directory, fileName).getAbsolutePath());
}
});
}
}, null);
}
private ParcelFileDescriptor getOutputFile(File directory, String fileName) {
File file = new File(directory, fileName);
try {
file.createNewFile();
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
} catch (Exception e) {
return null;
}
}
public interface CallbackPrint {
void onSuccess(String path);
void onFailure(String message);
}
}This code uses a `WebView` to load the HTML and then prints it to a PDF file. The `PdfPrint` class is a helper to manage the printing process asynchronously.
Integrating the Plugin with Unity Using C#
To build the .aar file, go to Build > Assemble Module, after the process has finished, you will find the aar in build\outputs\aar.
After building the `.aar` file, import it into your Unity project under the `Plugins/Android` folder.
Create a C# script to call the Java plugin:
using UnityEngine;
public class HtmlToPdfPlugin : MonoBehaviour
{
private const string PluginClassPath = "com.learn_html_to_pdf_unity_plugin.LearnHtmlToPdfPlugin";
[SerializeField] private string htmlContent = "<html><body><h1>Hello, World!</h1></body></html>";
[SerializeField] private string fileName = "HtmlContentOutput.pdf";
[SerializeField] private bool shouldOpenAutomatically = true;
private string outputPdfPath;
private class AndroidPdfCallback(
Action<string> onSuccess,
Action<string> onFailure
) : AndroidJavaProxy($"{PluginClassPath}$PdfCallback"), AndroidJavaProxy
{
private readonly Action<string> _onSuccess = onSuccess;
private readonly Action<string> _onFailure = onFailure;
// Called by Java
public void onSuccess(string pdfPath)
{
PrintLog.Log("PDF successfully saved at: " + pdfPath);
_onSuccess?.Invoke(pdfPath);
}
// Called by Java
public void onFailure(string errorMessage)
{
PrintLog.LogError("PDF generation failed: " + errorMessage);
_onFailure?.Invoke(errorMessage);
}
}
private void Awake()
{
outputPdfPath = System.IO.Path.Combine(Application.persistentDataPath, fileName);
}
private void Start()
{
ConvertHtmlToPdf();
}
private void ConvertHtmlToPdf()
{
var callback = new AndroidPdfCallback(OnSuccess, OnFailure);
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
using (var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
using (var pluginClass = new AndroidJavaClass(PluginClassPath))
{
pluginClass.CallStatic("convertHtmlStringToPdf", currentActivity,
htmlContent, outputPdfPath, callback, shouldOpenAutomatically);
}
}
}
This script initializes the Java plugin and provides a method to start the conversion. The callback handles success or failure messages.
Tips for Improving the Plugin
Add support for different page sizes and orientations.
Allow customization of margins and resolution.
Handle errors gracefully and provide detailed logs.
Optimize performance by reusing `WebView` instances.
Support asynchronous calls to avoid blocking the Unity main thread.
Summary
Building a native Android plugin for HTML to PDF conversion in Unity involves writing Java code to render HTML in a `WebView` and print it to PDF, then calling this code from Unity’s C# scripts. This approach gives developers full control over PDF generation without relying on external services. With proper setup and testing, you can integrate this functionality smoothly into your Unity Android projects.
Buy the existing plugin on the Unity Asset Store
This article covers the Android foundation. The production-ready plugin goes further — handling edge cases, platform differences, settings management, and a clean Inspector UI — across every major platform:
Be the First to Know When It Launches
Join the Sweet Home Studios email list and get notified the moment this asset goes live — plus early access and launch pricing.
👉 Sign up below ⬇️

Comments