All articles

Technical

How to Implement File Associations in Android TWAs

September 17, 2026 · 6 min read

Operating systems rely on file associations to connect file extensions to specific software. For progressive web apps running inside a Trusted Web Activity, implementing file associations allows your web-based software to behave like a native tool. When a user selects a file on their Android device, such as an image, text file, or custom document, your application can appear in the system list of compatible applications, open the file, and edit its contents.

Understanding the TWA File Handling Flow

Enabling file associations in an Android application compiled from a web application requires alignment between your server-side Web App Manifest configuration and the native client-side Android Manifest compilation. The entire communication loop operates using a defined sequence.

  • First, the Android operating system matches a file open action with the registered mime types in your app manifest.
  • Second, the Android system passes the file uri to your Trusted Web Activity wrapper.
  • Third, the Trusted Web Activity forwards this file reference to your web app runtime.
  • Finally, your client-side JavaScript reads the file content from the launch sequence.

Without correct configuration in both places, your application will fail to launch when files are selected, or it will launch into a default state without importing the targeted data.

Step 1: Declare File Handlers in the Web App Manifest

The standard way to declare file associations for progressive web apps is through the Web App Manifest file_handlers member. This configuration tells modern web engines which file types your app is capable of handling.

You must add a file_handlers array to your web app manifest JSON file. Each object in this array represents a specific file handler. It specifies the action url to load, the launch types, and the accepted file structures.

"file_handlers": [ { "action": "/open-file/", "name": "Project Viewer", "accept": { "text/plain": [".txt", ".md"], "application/json": [".json"] } } ]

The action property represents the landing page path that will handle the incoming payload. The accept object maps MIME types to arrays of file extensions. The browser and the compilation wrapper use this structure to generate native system registration schemes.

Step 2: Configure Android Manifest Intent Filters

While browsers process the Web App Manifest directly, native Android environments require system-level registration within the AndroidManifest.xml configuration inside your compiled app package. To intercept local file openings, your launcher activity must contain specific intent filters matching the MIME types defined in your web manifest.

To configure your compilation build, add intent filters inside your TWA activity block. These filters must listen for the VIEW action, accept default and browsable categories, and define the target mimeType matching your file requirements.

<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:mimeType="text/plain" /> <data android:mimeType="application/json" /> </intent-filter>

For custom file extensions that do not possess standard system-wide MIME types, you can configure data entries with both mimeType and pathPattern attributes to match specific extension tails. However, configuring standard MIME types is the most stable path for modern Android devices.

Step 3: Process Incoming Files with the Launch Queue API

Once the system launches your Trusted Web Activity with a file, you must retrieve this file payload in your progressive web app codebase. The web standard used for this mechanism is the Launch Queue API.

Your application code should check for the presence of the launchQueue interface on the window object. If present, you register a consumer function to catch the incoming parameters. This code must run early during your web application boot sequence to catch immediate launch intents.

if ('launchQueue' in window) { window.launchQueue.setConsumer(launchParams => { if (!launchParams.files || launchParams.files.length === 0) return; const fileHandle = launchParams.files[0]; fileHandle.getFile().then(file => { const reader = new FileReader(); reader.onload = e => { console.log(e.target.result); }; reader.readAsText(file); }); }); }

The launchParams object provides a files array containing FileSystemFileHandle elements. These handles allow your web application to read the file contents using standard web techniques like FileReader or stream readers, and if configured, write changes directly back to the original source location.

File Handler Configuration Mapping

To ensure a flawless connection between your web manifest, the native compilation, and the local file system, use this reference table for matching standard configurations:

File CategoryWeb Manifest MIME TypeExtension MappingAndroid MIME Entry
Plain Texttext/plain.txt, .logtext/plain
Markdowntext/markdown.mdtext/markdown
Imagesimage/png.pngimage/png
JSON Documentsapplication/json.jsonapplication/json
PDF Filesapplication/pdf.pdfapplication/pdf

Security, Verification, and Permissions

Android applications operating via Trusted Web Activities execute within a secured sandbox model. Passing local files from the operating system to the web engine is subject to specific validation rules to prevent unauthorized data access.

Digital Asset Links serve as the core security validator. The association between your native application package signature and your web domain must be verified. If this verification check fails, the TWA wrapper operates in fallback browser mode, which will block access to the native Launch Queue API for security reasons.

Furthermore, when accessing files via FileSystemFileHandle, your web runtime may trigger a system permission prompt. The user must explicitly approve access to allow write operations back to their local storage path. Implementing elegant error handling around these permission barriers prevents your application from freezing or crashing during unauthorized launch scenarios.

Ready to ship your Android app?

Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.

Build my app