Technical
Geolocation and Permission Delegation in TWAs
August 26, 2026 · 6 min read
When developers transition a Progressive Web App into a native Android app using a Trusted Web Activity, one of the primary concerns is how the application handles device hardware permissions. Unlike native Android applications or standard WebView wrappers, TWAs handle system-level access through a mechanism known as permission delegation. This architectural feature allows the TWA to bridge the gap between native Android security and web browser security seamlessly.
Understanding Permission Delegation in Trusted Web Activities
In a standard web browser, when a website requests access to sensitive APIs such as geolocation, the camera, or the microphone, the browser displays a permission prompt. In a native Android application, these prompts are handled by the Android operating system. If you run a web app inside a standard WebView, you must write extensive native Java or Kotlin boilerplate code to intercept web permission requests, map them to native Android permission requests, and pass the user choice back to the engine.
A Trusted Web Activity simplifies this process through permission delegation. Because the TWA is backed by the user custom tab custom browser engine, and identity is verified via Digital Asset Links, the native Android application wrapper can automatically delegate permission management to the underlying browser. When configured correctly, the browser checks if the native Android app already has the permission. If it does, the browser automatically grants the permission to the web app running inside the TWA without showing a secondary web prompt. This creates a single, native user experience.
The Core Benefits of Permission Delegation
Delegating permissions through a TWA provides several major advantages over traditional WebView development. Understanding these benefits helps developers structure their applications for the best user retention rates.
- Unified User Prompts: The user is only prompted once using the native Android dialog, rather than seeing a native prompt followed immediately by a web-based prompt.
- Seamless Integration: The JavaScript APIs inside your web application, such as
navigator.geolocation, function exactly as they would in a standard browser environment. No native bridge code is required. - Security Alignment: Because the relationship is verified via Digital Asset Links, the browser guarantees that only the authentic, signed Android application package can bypass secondary verification steps.
How Permission Delegation Works Behind the Scenes
The permission delegation mechanism relies on a helper library provided by Google, known as Android Browser Helper. This library sets up a service connection between your native app shell and the browser engine. When the web app requests a permission, the browser engine queries the host application through this service to verify if the native application has the corresponding Android system permission. The following table illustrates the operational differences in permission handling between WebViews and TWAs:
| Feature | Standard WebView Wrapper | Trusted Web Activity (TWA) |
|---|---|---|
| Setup Complexity | High (Requires custom WebChromeClient and manual bridge implementation) | Low (Handled automatically by the browser helper library) |
| User Experience | Often results in double prompting or fragmented interface dialogues | Clean, native Android system dialogue only |
| Security Context | Isolated; origin checks must be manually coded and validated | Cryptographically verified via Digital Asset Links |
| API Support | Limited or requires custom bridging for modern web APIs | Full, immediate access to all modern Chromium-supported Web APIs |
Configuring Geolocation in a TWA
To implement geolocation in your converted app, you must declare the appropriate permissions in your Android manifest and ensure the browser helper library is configured to delegate these requests. This process requires dual configuration: once in your Android package and once in your web app code.
1. Modifying the Android Manifest
First, your native wrapper app must declare that it intends to use location services. This is done by adding the following elements to your AndroidManifest.xml file:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If your application only requires approximate location details, you may declare the coarse location permission instead:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2. Enabling Delegation in the Launcher Activity
Your launcher activity must use the delegation settings provided by the Android Browser Helper. When constructing the TWA intent, delegation features for geolocation must be explicitly enabled. This is usually managed automatically if you use standard modern TWA building templates, but verifying the configuration ensures that native prompts route correctly to the underlying browser context.
Implementing Geolocation in Your Web Application
Once the native wrapper is configured, you do not need to write any custom Android native code to handle location tracking. You use standard, cross-platform JavaScript. This ensures that your single codebase functions correctly in standard desktop browsers, mobile browsers, and inside your converted Google Play application.
Here is an example of standard JavaScript you can use to retrieve the user location:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
When this code executes inside the TWA, the browser engine detects the request. It queries the native Android wrapper to see if ACCESS_FINE_LOCATION has been granted. If it has not, the native wrapper initiates the standard Android system permission dialogue. Once the user approves this native dialog, the permission status is propagated to the web engine, and your successCallback function executes seamlessly.
Handling Denials and Permission Edge Cases
A robust application must gracefully handle scenarios where users deny permission requests. Users may reject permission prompts during the initial setup or revoke permissions later via their Android system settings. Your web-based application code should check permission status before attempting to trigger hardware features.
Using the Query Permissions API allows your web app to inspect the current state of geolocation permissions prior to calling the location service:
navigator.permissions.query({ name: 'geolocation' }).then(function(result) { if (result.state === 'granted') { // Proceed with location tracking } else if (result.state === 'prompt') { // Notify the user why location access is beneficial before triggering the prompt } else { // Handle denied state gracefully by offering manual input alternatives } });
By checking the state first, you can build custom user interfaces that explain exactly why your application needs location details, improving permission opt-in rates. If the permission is denied, your application should degrade gracefully, for example, by allowing users to enter their city or postcode manually via a text field instead of failing completely.
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